summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--abicheck/abi-compliance-checker.pl7325
-rwxr-xr-xabicheck/run_abi_test7
-rw-r--r--apt-pkg/acquire-item.cc31
-rw-r--r--apt-pkg/acquire-item.h2
-rw-r--r--apt-pkg/algorithms.cc51
-rw-r--r--apt-pkg/algorithms.h4
-rw-r--r--apt-pkg/cachefilter.cc11
-rw-r--r--apt-pkg/cachefilter.h84
-rw-r--r--apt-pkg/cacheset.cc64
-rw-r--r--apt-pkg/cacheset.h13
-rw-r--r--apt-pkg/contrib/cmndline.cc48
-rw-r--r--apt-pkg/contrib/cmndline.h6
-rw-r--r--apt-pkg/contrib/configuration.cc12
-rw-r--r--apt-pkg/contrib/configuration.h1
-rw-r--r--apt-pkg/contrib/fileutl.cc31
-rw-r--r--apt-pkg/contrib/fileutl.h3
-rw-r--r--apt-pkg/contrib/strutl.cc12
-rw-r--r--apt-pkg/contrib/strutl.h4
-rw-r--r--apt-pkg/deb/deblistparser.cc104
-rw-r--r--apt-pkg/deb/dpkgpm.cc59
-rw-r--r--apt-pkg/indexrecords.cc17
-rw-r--r--apt-pkg/policy.cc25
-rw-r--r--apt-pkg/tagfile.cc59
-rw-r--r--apt-pkg/tagfile.h1
-rw-r--r--apt-pkg/vendorlist.cc2
-rw-r--r--apt-private/acqprogress.cc309
-rw-r--r--apt-private/acqprogress.h38
-rw-r--r--apt-private/makefile28
-rw-r--r--apt-private/private-cachefile.cc109
-rw-r--r--apt-private/private-cachefile.h51
-rw-r--r--apt-private/private-cacheset.cc63
-rw-r--r--apt-private/private-cacheset.h265
-rw-r--r--apt-private/private-cmndline.cc268
-rw-r--r--apt-private/private-cmndline.h10
-rw-r--r--apt-private/private-install.cc852
-rw-r--r--apt-private/private-install.h181
-rw-r--r--apt-private/private-list.cc167
-rw-r--r--apt-private/private-list.h9
-rw-r--r--apt-private/private-main.cc26
-rw-r--r--apt-private/private-main.h9
-rw-r--r--apt-private/private-moo.cc193
-rw-r--r--apt-private/private-moo.h12
-rw-r--r--apt-private/private-output.cc753
-rw-r--r--apt-private/private-output.h49
-rw-r--r--apt-private/private-search.cc99
-rw-r--r--apt-private/private-search.h9
-rw-r--r--apt-private/private-show.cc122
-rw-r--r--apt-private/private-show.h12
-rw-r--r--apt-private/private-update.cc93
-rw-r--r--apt-private/private-update.h8
-rw-r--r--apt-private/private-upgrade.cc53
-rw-r--r--apt-private/private-upgrade.h11
-rw-r--r--cmdline/apt-cache.cc116
-rw-r--r--cmdline/apt-cdrom.cc34
-rw-r--r--cmdline/apt-config.cc23
-rw-r--r--cmdline/apt-get.cc1991
-rwxr-xr-xcmdline/apt-key171
-rw-r--r--cmdline/apt-mark.cc21
-rw-r--r--cmdline/apt.cc158
-rw-r--r--cmdline/makefile19
-rw-r--r--debian/apt.install.in (renamed from debian/apt.install)1
-rw-r--r--debian/apt.lintian-overrides2
-rw-r--r--debian/apt.postinst14
-rw-r--r--debian/changelog89
-rwxr-xr-xdebian/rules4
-rw-r--r--doc/apt.conf.5.xml23
-rw-r--r--ftparchive/writer.cc3
-rw-r--r--po/fr.po14
-rw-r--r--po/ja.po34
-rw-r--r--test/integration/framework95
-rw-r--r--test/integration/rexexpired.pubbin0 -> 1200 bytes
-rw-r--r--test/integration/rexexpired.secbin0 -> 2502 bytes
-rwxr-xr-xtest/integration/skip-avoid-avoiding-breaks-predepends2
-rwxr-xr-xtest/integration/test-apt-cdrom2
-rwxr-xr-xtest/integration/test-apt-get-autoremove10
-rwxr-xr-xtest/integration/test-apt-key107
-rwxr-xr-xtest/integration/test-bug-407511-fail-invalid-default-release4
-rwxr-xr-xtest/integration/test-bug-507998-dist-upgrade-recommends25
-rwxr-xr-xtest/integration/test-bug-543966-downgrade-below-1000-pin81
-rwxr-xr-xtest/integration/test-bug-602412-dequote-redirect4
-rwxr-xr-xtest/integration/test-bug-604222-new-and-autoremove2
-rwxr-xr-xtest/integration/test-bug-604401-files-are-directories10
-rwxr-xr-xtest/integration/test-bug-611729-mark-as-manual20
-rwxr-xr-xtest/integration/test-bug-612099-multiarch-conflicts16
-rwxr-xr-xtest/integration/test-bug-612557-garbage-upgrade4
-rwxr-xr-xtest/integration/test-bug-612958-use-dpkg-multiarch-config4
-rwxr-xr-xtest/integration/test-bug-613420-new-garbage-dependency2
-rwxr-xr-xtest/integration/test-bug-618288-multiarch-same-lockstep2
-rwxr-xr-xtest/integration/test-bug-64141-install-dependencies-for-on-hold2
-rwxr-xr-xtest/integration/test-bug-673536-pre-depends-breaks-loop4
-rwxr-xr-xtest/integration/test-bug-679371-apt-get-autoclean-multiarch4
-rwxr-xr-xtest/integration/test-bug-686346-package-missing-architecture4
-rwxr-xr-xtest/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch96
-rwxr-xr-xtest/integration/test-bug-717891-abolute-uris-for-proxies4
-rwxr-xr-xtest/integration/test-bug-719263-print-uris-removes-authentication41
-rwxr-xr-xtest/integration/test-compressed-indexes34
-rwxr-xr-xtest/integration/test-cve-2013-1051-InRelease-parsing2
-rwxr-xr-xtest/integration/test-disappearing-packages2
-rwxr-xr-xtest/integration/test-pdiff-usage4
-rwxr-xr-xtest/integration/test-policy-pinning8
-rwxr-xr-xtest/integration/test-releasefile-valid-until32
-rwxr-xr-xtest/integration/test-releasefile-verification35
-rwxr-xr-xtest/integration/test-ubuntu-bug-761175-remove-purge6
-rwxr-xr-xtest/integration/test-ubuntu-bug-784473-InRelease-one-message-only2
-rw-r--r--test/libapt/configuration_test.cc4
-rw-r--r--test/libapt/fileutl_test.cc42
-rw-r--r--test/libapt/makefile5
-rwxr-xr-xtest/libapt/run-tests20
109 files changed, 5413 insertions, 9821 deletions
diff --git a/Makefile b/Makefile
index 47fc23656..fb843983c 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ default: startup all
all headers library clean veryclean binary program doc manpages debiandoc test update-po startup dirs:
$(MAKE) -C apt-pkg $@
$(MAKE) -C apt-inst $@
+ $(MAKE) -C apt-private $@
$(MAKE) -C methods $@
$(MAKE) -C cmdline $@
$(MAKE) -C ftparchive $@
diff --git a/abicheck/abi-compliance-checker.pl b/abicheck/abi-compliance-checker.pl
deleted file mode 100644
index 7fd8ab173..000000000
--- a/abicheck/abi-compliance-checker.pl
+++ /dev/null
@@ -1,7325 +0,0 @@
-#!/usr/bin/perl
-###########################################################################
-# ABI-compliance-checker v1.13, lightweight tool for statically checking
-# backward binary compatibility of shared C/C++ libraries in Linux.
-# Copyright (C) The Linux Foundation
-# Copyright (C) Institute for System Programming, RAS
-# Author: Andrey Ponomarenko
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-###########################################################################
-use Getopt::Long;
-Getopt::Long::Configure ("posix_default", "no_ignore_case");
-use Data::Dumper;
-
-my $ABI_COMPLIANCE_CHECKER_VERSION = "1.13";
-my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $HeaderCheckingMode_Separately, $GenerateDescriptor, $TestSystem, $DumpInfo_DescriptorPath, $CheckHeadersOnly, $InterfacesListPath, $AppPath, $ShowExpendTime);
-
-my $CmdName = get_FileName($0);
-GetOptions("h|help!" => \$Help,
- "v|version!" => \$ShowVersion,
-#general options
- "l|library=s" => \$TargetLibraryName,
- "d1|descriptor1=s" => \$Descriptor{1}{"Path"},
- "d2|descriptor2=s" => \$Descriptor{2}{"Path"},
-#extra options
- "app|application=s" => \$AppPath,
- "symbols_list|int_list=s" => \$InterfacesListPath,
- "dump_abi|dump_info=s" => \$DumpInfo_DescriptorPath,
- "headers_only!" => \$CheckHeadersOnly,
-#other options
- "d|descriptor_template!" => \$GenerateDescriptor,
- "separately!" => \$HeaderCheckingMode_Separately,
- "test!" => \$TestSystem,
- "time!" => \$ShowExpendTime
-) or exit(1);
-
-sub HELP_MESSAGE()
-{
- print STDERR <<"EOM"
-
-NAME:
- $CmdName - check ABI compatibility of shared C/C++ library versions
-
-DESCRIPTION:
- Lightweight tool for statically checking backward binary compatibility of shared C/C++ libraries
- in Linux. It checks header files along with shared objects in two library versions and searches
- for ABI changes that may lead to incompatibility. Breakage of the binary compatibility may result
- in crashing or incorrect behavior of applications built with an old version of a library when
- it is running with a new one.
-
- ABI Compliance Checker was intended for library developers that are interested in ensuring
- backward binary compatibility. Also it can be used for checking forward binary compatibility
- and checking applications portability to the new library version.
-
- This tool is free software: you can redistribute it and/or modify it under the terms of the GNU GPL.
-
-USAGE:
- $CmdName [options]
-
-EXAMPLE OF USE:
- $CmdName -l <library_name> -d1 <1st_version_descriptor> -d2 <2nd_version_descriptor>
-
-GENERAL OPTIONS:
- -h|-help
- Print this help.
-
- -v|-version
- Print version.
-
- -l|-library <name>
- Library name (without version).
- It affects only on the path and the title of the report.
-
- -d1|-descriptor1 <path>
- Path to descriptor of 1st library version.
-
- -d2|-descriptor2 <path>
- Path to descriptor of 2nd library version.
-
-EXTRA OPTIONS:
- -app|-application <path>
- This option allow to specify the application that should be tested for portability
- to the new library version.
-
- -dump_abi|-dump_info <descriptor_path>
- Dump library ABI information using specified descriptor.
- This command will create '<library>_<ver1>.abi.tar.gz' file in the directory 'abi_dumps/<library>/'.
- You can transfer it anywhere and pass instead of library descriptor.
-
- -headers_only
- Check header files without shared objects. It is easy to run, but may provide
- a low quality ABI compliance report with false positives and without
- detecting of added/withdrawn interfaces.
-
- -symbols_list|-int_list <path>
- This option allow to specify a file with a list of interfaces (mangled names in C++)
- that should be checked, other library interfaces will not be checked.
-
-OTHER OPTIONS:
- -d|-descriptor_template
- Create library descriptor template 'library-descriptor.xml' in the current directory.
-
- -separately
- Check headers individually. This mode requires more time for checking ABI compliance,
- but possible compiler errors in one header can't affect others.
-
- -test
- Run internal tests (create two binary-incompatible versions of an artificial library
- and run ABI-Compliance-Checker on it).
-
-DESCRIPTOR EXAMPLE:
- <version>
- 1.28.0
- </version>
-
- <headers>
- /usr/local/atk/atk-1.28.0/include/
- </headers>
-
- <libs>
- /usr/local/atk/atk-1.28.0/lib/libatk-1.0.so
- </libs>
-
- <include_paths>
- /usr/include/glib-2.0/
- /usr/lib/glib-2.0/include/
- </include_paths>
-
-
-Report bugs to <abi-compliance-checker\@linuxtesting.org>
-For more information, please see: http://ispras.linux-foundation.org/index.php/ABI_compliance_checker
-EOM
- ;
-}
-
-my $Descriptor_Template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<descriptor>
-
-<!-- Template for the library version descriptor -->
-
-<!--
- Necessary sections
- -->
-
-<version>
- <!-- Version of the library -->
-</version>
-
-<headers>
- <!-- The list of paths to header files and/or
- directories with header files, one per line -->
-</headers>
-
-<libs>
- <!-- The list of paths to shared objects and/or
- directories with shared objects, one per line -->
-</libs>
-
-<!--
- Additional sections
- -->
-
-<include_paths>
- <!-- The list of paths to be searched for header files
- needed for compiling of library headers, one per line -->
-</include_paths>
-
-<gcc_options>
- <!-- Additional gcc options, one per line -->
-</gcc_options>
-
-<opaque_types>
- <!-- The list of opaque types, one per line -->
-</opaque_types>
-
-<skip_interfaces>
- <!-- The list of functions (mangled/symbol names in C++)
- that should be skipped while testing, one per line -->
-</skip_interfaces>
-
-<include_preamble>
- <!-- The list of header files that should be included before other headers, one per line.
- For example, it is a tree.h for libxml2 and ft2build.h for freetype2 -->
-</include_preamble>
-
-</descriptor>";
-
-my %Operator_Indication = (
-"not" => "~",
-"assign" => "=",
-"andassign" => "&=",
-"orassign" => "|=",
-"xorassign" => "^=",
-"or" => "|",
-"xor" => "^",
-"addr" => "&",
-"and" => "&",
-"lnot" => "!",
-"eq" => "==",
-"ne" => "!=",
-"lt" => "<",
-"lshift" => "<<",
-"lshiftassign" => "<<=",
-"rshiftassign" => ">>=",
-"call" => "()",
-"mod" => "%",
-"modassign" => "%=",
-"subs" => "[]",
-"land" => "&&",
-"lor" => "||",
-"rshift" => ">>",
-"ref" => "->",
-"le" => "<=",
-"deref" => "*",
-"mult" => "*",
-"preinc" => "++",
-"delete" => " delete",
-"vecnew" => " new[]",
-"vecdelete" => " delete[]",
-"predec" => "--",
-"postinc" => "++",
-"postdec" => "--",
-"plusassign" => "+=",
-"plus" => "+",
-"minus" => "-",
-"minusassign" => "-=",
-"gt" => ">",
-"ge" => ">=",
-"new" => " new",
-"multassign" => "*=",
-"divassign" => "/=",
-"div" => "/",
-"neg" => "-",
-"pos" => "+",
-"memref" => "->*",
-"compound" => ","
-);
-
-sub num_to_str($)
-{
- my $Number = $_[0];
- if(int($Number)>3)
- {
- return $Number."th";
- }
- elsif(int($Number)==1)
- {
- return "1st";
- }
- elsif(int($Number)==2)
- {
- return "2nd";
- }
- elsif(int($Number)==3)
- {
- return "3rd";
- }
- else
- {
- return "";
- }
-}
-
-#Global variables
-my $REPORT_PATH;
-my %ERR_PATH;
-my $POINTER_SIZE;
-my $MAX_COMMAND_LINE_ARGUMENTS = 4096;
-my %Cache;
-my %FuncAttr;
-my %LibInfo;
-my %HeaderCompileError;
-my $StartTime;
-my %CompilerOptions;
-my %AddedInt;
-my %WithdrawnInt;
-my @RecurLib;
-my %CheckedSoLib;
-
-#Constants checking
-my %ConstantsSrc;
-my %Constants;
-
-#Types
-my %TypeDescr;
-my %TemplateInstance_Func;
-my %TemplateInstance;
-my %OpaqueTypes;
-my %Tid_TDid;
-my %CheckedTypes;
-my %Typedef_BaseName;
-my %StdCxxTypedef;
-my %TName_Tid;
-my %EnumMembName_Id;
-
-#Interfaces
-my %FuncDescr;
-my %ClassFunc;
-my %ClassVirtFunc;
-my %ClassIdVirtFunc;
-my %ClassId;
-my %tr_name;
-my %mangled_name;
-my %InternalInterfaces;
-my %InterfacesList;
-my %InterfacesList_App;
-my %CheckedInterfaces;
-my %DepInterfaces;
-
-#Headers
-my %Include_Preamble;
-my %Headers;
-my %HeaderName_Destinations;
-my %Header_Dependency;
-
-#Shared objects
-my %SoLib_DefaultPath;
-
-#Merging
-my %CompleteSignature;
-my @RecurTypes;
-my %Interface_Library;
-my %Library_Interface;
-my %Language;
-my %SoNames_All;
-my $Version;
-
-#Symbols versioning
-my %SymVer;
-
-#Problem descriptions
-my %CompatProblems;
-my %ConstantProblems;
-
-#Rerorts
-my $ContentID = 1;
-my $ContentSpanStart = "<span class=\"section\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
-my $ContentSpanEnd = "</span>\n";
-my $ContentDivStart = "<div id=\"CONTENT_ID\" style=\"display:none;\">\n";
-my $ContentDivEnd = "</div>\n";
-my $Content_Counter = 0;
-
-sub readDescriptor($)
-{
- my $LibVersion = $_[0];
- if(not -e $Descriptor{$LibVersion}{"Path"})
- {
- return;
- }
- my $Descriptor_File = readFile($Descriptor{$LibVersion}{"Path"});
- $Descriptor_File =~ s/\/\*(.|\n)+?\*\///g;
- $Descriptor_File =~ s/<\!--(.|\n)+?-->//g;
- if(not $Descriptor_File)
- {
- print "ERROR: descriptor d$LibVersion is empty\n";
- exit(1);
- }
- $Descriptor{$LibVersion}{"Version"} = parseTag(\$Descriptor_File, "version");
- if(not $Descriptor{$LibVersion}{"Version"})
- {
- print "ERROR: version in the descriptor d$LibVersion was not specified (section <version>)\n\n";
- exit(1);
- }
- $Descriptor{$LibVersion}{"Headers"} = parseTag(\$Descriptor_File, "headers");
- if(not $Descriptor{$LibVersion}{"Headers"})
- {
- print "ERROR: header files in the descriptor d$LibVersion were not specified (section <headers>)\n";
- exit(1);
- }
- if(not $CheckHeadersOnly)
- {
- $Descriptor{$LibVersion}{"Libs"} = parseTag(\$Descriptor_File, "libs");
- if(not $Descriptor{$LibVersion}{"Libs"})
- {
- print "ERROR: shared objects in the descriptor d$LibVersion were not specified (section <libs>)\n";
- exit(1);
- }
- }
- $Descriptor{$LibVersion}{"Include_Paths"} = parseTag(\$Descriptor_File, "include_paths");
- $Descriptor{$LibVersion}{"Gcc_Options"} = parseTag(\$Descriptor_File, "gcc_options");
- foreach my $Option (split("\n", $Descriptor{$LibVersion}{"Gcc_Options"}))
- {
- $Option =~ s/\A\s+|\s+\Z//g;
- next if(not $Option);
- $CompilerOptions{$LibVersion} .= " ".$Option;
- }
- $Descriptor{$LibVersion}{"Opaque_Types"} = parseTag(\$Descriptor_File, "opaque_types");
- foreach my $Type_Name (split("\n", $Descriptor{$LibVersion}{"Opaque_Types"}))
- {
- $Type_Name =~ s/\A\s+|\s+\Z//g;
- next if(not $Type_Name);
- $OpaqueTypes{$LibVersion}{$Type_Name} = 1;
- }
- $Descriptor{$LibVersion}{"Skip_interfaces"} = parseTag(\$Descriptor_File, "skip_interfaces");
- foreach my $Interface_Name (split("\n", $Descriptor{$LibVersion}{"Skip_interfaces"}))
- {
- $Interface_Name =~ s/\A\s+|\s+\Z//g;
- next if(not $Interface_Name);
- $InternalInterfaces{$LibVersion}{$Interface_Name} = 1;
- }
- $Descriptor{$LibVersion}{"Include_Preamble"} = parseTag(\$Descriptor_File, "include_preamble");
- my $Position = 0;
- foreach my $Header_Name (split("\n", $Descriptor{$LibVersion}{"Include_Preamble"}))
- {
- $Header_Name =~ s/\A\s+|\s+\Z//g;
- next if(not $Header_Name);
- $Include_Preamble{$LibVersion}{$Header_Name}{"Position"} = $Position;
- $Position+=1;
- }
- my $Descriptors_Dir = "descriptors_storage/$TargetLibraryName";
- system("mkdir", "-p", $Descriptors_Dir);
- my $Descriptor_Name = $TargetLibraryName."_".$Descriptor{$LibVersion}{"Version"}.".desc";
- if($Descriptor{$LibVersion}{"Path"} ne $Descriptors_Dir."/".$Descriptor_Name)
- {
- system("cp", "-f", $Descriptor{$LibVersion}{"Path"}, $Descriptors_Dir."/".$Descriptor_Name);
- }
- $ERR_PATH{$LibVersion} = "header_compile_errors/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"};
-}
-
-sub parseTag($$)
-{
- my ($CodeRef, $Tag) = @_;
- return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
- if(${$CodeRef} =~ s/\<$Tag\>((.|\n)+?)\<\/$Tag\>//)
- {
- my $Content = $1;
- $Content=~s/(\A\s+|\s+\Z)//g;
- return $Content;
- }
- else
- {
- return "";
- }
-}
-
-my %check_node=(
-"array_type"=>1,
-"binfo"=>1,
-"boolean_type"=>1,
-"complex_type"=>1,
-"const_decl"=>1,
-"enumeral_type"=>1,
-"field_decl"=>1,
-"function_decl"=>1,
-"function_type"=>1,
-"identifier_node"=>1,
-"integer_cst"=>1,
-"integer_type"=>1,
-"method_type"=>1,
-"namespace_decl"=>1,
-"parm_decl"=>1,
-"pointer_type"=>1,
-"real_cst"=>1,
-"real_type"=>1,
-"record_type"=>1,
-"reference_type"=>1,
-"string_cst"=>1,
-"template_decl"=>1,
-"template_type_parm"=>1,
-"tree_list"=>1,
-"tree_vec"=>1,
-"type_decl"=>1,
-"union_type"=>1,
-"var_decl"=>1,
-"void_type"=>1);
-
-sub getInfo($)
-{
- my $InfoPath = $_[0];
- return if(not $InfoPath or not -f $InfoPath);
- my $InfoPath_New = $InfoPath.".1";
- #my $Keywords = join("\\|", keys(%check_node));#|grep "$Keywords"
- system("sed ':a;N;\$!ba;s/\\n[^\@]//g' ".esc($InfoPath)."|sed 's/ [ ]\\+/ /g' > ".esc($InfoPath_New));
- system("rm", "-fr", $InfoPath);
- #getting info
- open(INFO, $InfoPath_New) || die ("can't open file '\$InfoPath_New\': $!\n");
- while(<INFO>)
- {
- chomp;
- if(/\A@([0-9]+)[ ]+([a-zA-Z_]+)[ ]+(.*)\Z/)
- {
- next if(not $check_node{$2});
- $LibInfo{$Version}{$1}{"info_type"}=$2;
- $LibInfo{$Version}{$1}{"info"}=$3;
- }
- }
- close(INFO);
- system("rm", "-fr", $InfoPath_New);
- #processing info
- setTemplateParams_All();
- getTypeDescr_All();
- getFuncDescr_All();
- getVarDescr_All();
- %LibInfo = ();
- %TemplateInstance = ();
-}
-
-sub setTemplateParams_All()
-{
- foreach (keys(%{$LibInfo{$Version}}))
- {
- if($LibInfo{$Version}{$_}{"info_type"} eq "template_decl")
- {
- setTemplateParams($_);
- }
- }
-}
-
-sub setTemplateParams($)
-{
- my $TypeInfoId = $_[0];
- my $Info = $LibInfo{$Version}{$TypeInfoId}{"info"};
- if($Info =~ /(inst|spcs)[ ]*:[ ]*@([0-9]+) /)
- {
- my $TmplInst_InfoId = $2;
- setTemplateInstParams($TmplInst_InfoId);
- my $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
- while($TmplInst_Info =~ /chan[ ]*:[ ]*@([0-9]+) /)
- {
- $TmplInst_InfoId = $1;
- $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
- setTemplateInstParams($TmplInst_InfoId);
- }
- }
-}
-
-sub setTemplateInstParams($)
-{
- my $TmplInst_Id = $_[0];
- my $Info = $LibInfo{$Version}{$TmplInst_Id}{"info"};
- my ($Params_InfoId, $ElemId) = ();
- if($Info =~ /purp[ ]*:[ ]*@([0-9]+) /)
- {
- $Params_InfoId = $1;
- }
- if($Info =~ /valu[ ]*:[ ]*@([0-9]+) /)
- {
- $ElemId = $1;
- }
- if($Params_InfoId and $ElemId)
- {
- my $Params_Info = $LibInfo{$Version}{$Params_InfoId}{"info"};
- while($Params_Info =~ s/ ([0-9]+)[ ]*:[ ]*@([0-9]+) //)
- {
- my ($Param_Pos, $Param_TypeId) = ($1, $2);
- return if($LibInfo{$Version}{$Param_TypeId}{"info_type"} eq "template_type_parm");
- if($LibInfo{$ElemId}{"info_type"} eq "function_decl")
- {
- $TemplateInstance_Func{$Version}{$ElemId}{$Param_Pos} = $Param_TypeId;
- }
- else
- {
- $TemplateInstance{$Version}{getTypeDeclId($ElemId)}{$ElemId}{$Param_Pos} = $Param_TypeId;
- }
- }
- }
-}
-
-sub getTypeDeclId($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+)/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub isFuncPtr($)
-{
- my $Ptd = pointTo($_[0]);
- if($Ptd)
- {
- if(($LibInfo{$Version}{$_[0]}{"info"} =~ m/unql[ ]*:/) and not ($LibInfo{$Version}{$_[0]}{"info"} =~ m/qual[ ]*:/))
- {
- return 0;
- }
- 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"))
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return 0;
- }
-}
-
-sub pointTo($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+)/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getTypeDescr_All()
-{
- foreach (sort {int($a)<=>int($b)} keys(%{$LibInfo{$Version}}))
- {
- if($LibInfo{$Version}{$_}{"info_type"}=~/_type\Z/ and $LibInfo{$Version}{$_}{"info_type"}!~/function_type|method_type/)
- {
- getTypeDescr(getTypeDeclId($_), $_);
- }
- }
- $TypeDescr{$Version}{""}{-1}{"Name"} = "...";
- $TypeDescr{$Version}{""}{-1}{"Type"} = "Intrinsic";
- $TypeDescr{$Version}{""}{-1}{"Tid"} = -1;
-}
-
-sub getTypeDescr($$)
-{
- my ($TypeDeclId, $TypeId) = @_;
- $Tid_TDid{$Version}{$TypeId} = $TypeDeclId;
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTypeAttr($TypeDeclId, $TypeId);
- if(not $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
- {
- delete($TypeDescr{$Version}{$TypeDeclId}{$TypeId});
- return;
- }
- if(not $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}})
- {
- $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
- }
-}
-
-sub getTypeAttr($$)
-{
- my ($TypeDeclId, $TypeId) = @_;
- my ($BaseTypeSpec, %TypeAttr) = ();
- if($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
- {
- return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
- }
- $TypeAttr{"Tid"} = $TypeId;
- $TypeAttr{"TDid"} = $TypeDeclId;
- $TypeAttr{"Type"} = getTypeType($TypeDeclId, $TypeId);
- if($TypeAttr{"Type"} eq "Unknown")
- {
- return ();
- }
- elsif($TypeAttr{"Type"} eq "FuncPtr")
- {
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getFuncPtrAttr(pointTo($TypeId), $TypeDeclId, $TypeId);
- $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
- return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
- }
- elsif($TypeAttr{"Type"} eq "Array")
- {
- ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
- my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
- my $ArrayElemNum = getSize($TypeId)/8;
- $ArrayElemNum = $ArrayElemNum/$BaseTypeAttr{"Size"} if($BaseTypeAttr{"Size"});
- $TypeAttr{"Size"} = $ArrayElemNum;
- if($ArrayElemNum)
- {
- $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[".$ArrayElemNum."]";
- }
- else
- {
- $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[]";
- }
- $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
- $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
- $TypeAttr{"Header"} = $BaseTypeAttr{"Header"};
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
- $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
- return %TypeAttr;
- }
- elsif($TypeAttr{"Type"} =~ /Intrinsic|Union|Struct|Enum|Class/)
- {
- if($TemplateInstance{$Version}{$TypeDeclId}{$TypeId})
- {
- my @Template_Params = ();
- foreach my $Param_Pos (sort {int($a)<=>int($b)} keys(%{$TemplateInstance{$Version}{$TypeDeclId}{$TypeId}}))
- {
- my $Type_Id = $TemplateInstance{$Version}{$TypeDeclId}{$TypeId}{$Param_Pos};
- my $Param = get_TemplateParam($Type_Id);
- if($Param eq "")
- {
- return ();
- }
- @Template_Params = (@Template_Params, $Param);
- }
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
- $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}."< ".join(", ", @Template_Params)." >";
- $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = correctName($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"});
- $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
- return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
- }
- else
- {
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
- return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
- }
- }
- else
- {
- ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
- my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
- if($BaseTypeSpec and $BaseTypeAttr{"Name"})
- {
- if(($TypeAttr{"Type"} eq "Pointer") and $BaseTypeAttr{"Name"}=~/\([\*]+\)/)
- {
- $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
- $TypeAttr{"Name"} =~ s/\(([*]+)\)/($1*)/g;
- }
- else
- {
- $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}." ".$BaseTypeSpec;
- }
- }
- elsif($BaseTypeAttr{"Name"})
- {
- $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
- }
- if($TypeAttr{"Type"} eq "Typedef")
- {
- $TypeAttr{"Name"} = getNameByInfo($TypeDeclId);
- $TypeAttr{"NameSpace"} = getNameSpace($TypeDeclId);
- if($TypeAttr{"NameSpace"})
- {
- $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
- }
- ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeDeclId);
- if($TypeAttr{"NameSpace"}=~/\Astd(::|\Z)/ and $BaseTypeAttr{"NameSpace"}=~/\Astd(::|\Z)/)
- {
- $StdCxxTypedef{$Version}{$BaseTypeAttr{"Name"}} = $TypeAttr{"Name"};
- }
- $Typedef_BaseName{$Version}{$TypeAttr{"Name"}} = $BaseTypeAttr{"Name"};
- }
- if(not $TypeAttr{"Size"})
- {
- if($TypeAttr{"Type"} eq "Pointer")
- {
- $TypeAttr{"Size"} = $POINTER_SIZE;
- }
- else
- {
- $TypeAttr{"Size"} = $BaseTypeAttr{"Size"};
- }
- }
- $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
- $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
- $TypeAttr{"Header"} = $BaseTypeAttr{"Header"} if(not $TypeAttr{"Header"});
- %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
- $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
- return %TypeAttr;
- }
-}
-
-sub get_TemplateParam($)
-{
- my $Type_Id = $_[0];
- if(getNodeType($Type_Id) eq "integer_cst")
- {
- return getNodeIntCst($Type_Id);
- }
- elsif(getNodeType($Type_Id) eq "string_cst")
- {
- return getNodeStrCst($Type_Id);
- }
- else
- {
- my $Type_DId = getTypeDeclId($Type_Id);
- my %ParamAttr = getTypeAttr($Type_DId, $Type_Id);
- if(not $ParamAttr{"Name"})
- {
- return "";
- }
- if($ParamAttr{"Name"}=~/\>/)
- {
- if($StdCxxTypedef{$Version}{$ParamAttr{"Name"}})
- {
- return $StdCxxTypedef{$Version}{$ParamAttr{"Name"}};
- }
- elsif(my $Covered = cover_stdcxx_typedef($ParamAttr{"Name"}))
- {
- return $Covered;
- }
- else
- {
- return $ParamAttr{"Name"};
- }
- }
- else
- {
- return $ParamAttr{"Name"};
- }
- }
-}
-
-sub cover_stdcxx_typedef($)
-{
- my $TypeName = $_[0];
- my $TypeName_Covered = $TypeName;
- while($TypeName=~s/>[ ]*(const|volatile|restrict| |\*|\&)\Z/>/g){};
- if(my $Cover = $StdCxxTypedef{$Version}{$TypeName})
- {
- $TypeName = esc_l($TypeName);
- $TypeName_Covered=~s/$TypeName/$Cover /g;
- }
- return correctName($TypeName_Covered);
-}
-
-sub getNodeType($)
-{
- return $LibInfo{$Version}{$_[0]}{"info_type"};
-}
-
-sub getNodeIntCst($)
-{
- my $CstId = $_[0];
- my $CstTypeId = getTreeAttr($CstId, "type");
- if($EnumMembName_Id{$Version}{$CstId})
- {
- return $EnumMembName_Id{$Version}{$CstId};
- }
- elsif($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*([^ ]+) /)
- {
- if($1 eq "0")
- {
- if(getNodeType($CstTypeId) eq "boolean_type")
- {
- return "false";
- }
- else
- {
- return "0";
- }
- }
- elsif($1 eq "1")
- {
- if(getNodeType($CstTypeId) eq "boolean_type")
- {
- return "true";
- }
- else
- {
- return "1";
- }
- }
- else
- {
- return $1;
- }
- }
- else
- {
- return "";
- }
-}
-
-sub getNodeStrCst($)
-{
- if($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*(.+)[ ]+lngt/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub esc_l($)
-{
- my $String = $_[0];
- $String=~s/([()*])/\\$1/g;
- return $String;
-}
-
-sub getFuncPtrAttr($$$)
-{
- my ($FuncTypeId, $TypeDeclId, $TypeId) = @_;
- my $FuncInfo = $LibInfo{$Version}{$FuncTypeId}{"info"};
- my $FuncInfo_Type = $LibInfo{$Version}{$FuncTypeId}{"info_type"};
- my $FuncPtrCorrectName = "";
- my %TypeAttr = ("Size"=>$POINTER_SIZE, "Type"=>"FuncPtr", "TDid"=>$TypeDeclId, "Tid"=>$TypeId);
- my @ParamTypeName;
- if($FuncInfo =~ /retn[ ]*:[ ]*\@([0-9]+) /)
- {
- my $ReturnTypeId = $1;
- my %ReturnAttr = getTypeAttr(getTypeDeclId($ReturnTypeId), $ReturnTypeId);
- $FuncPtrCorrectName .= $ReturnAttr{"Name"};
- $TypeAttr{"Return"} = $ReturnTypeId;
- }
- if($FuncInfo =~ /prms[ ]*:[ ]*@([0-9]+) /)
- {
- my $ParamTypeInfoId = $1;
- my $Position = 0;
- while($ParamTypeInfoId)
- {
- my $ParamTypeInfo = $LibInfo{$Version}{$ParamTypeInfoId}{"info"};
- last if($ParamTypeInfo !~ /valu[ ]*:[ ]*@([0-9]+) /);
- my $ParamTypeId = $1;
- my %ParamAttr = getTypeAttr(getTypeDeclId($ParamTypeId), $ParamTypeId);
- last if($ParamAttr{"Name"} eq "void");
- $TypeAttr{"Memb"}{$Position}{"type"} = $ParamTypeId;
- push(@ParamTypeName, $ParamAttr{"Name"});
- last if($ParamTypeInfo !~ /chan[ ]*:[ ]*@([0-9]+) /);
- $ParamTypeInfoId = $1;
- $Position+=1;
- }
- }
- if($FuncInfo_Type eq "function_type")
- {
- $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
- }
- elsif($FuncInfo_Type eq "method_type")
- {
- if($FuncInfo =~ /clas[ ]*:[ ]*@([0-9]+) /)
- {
- my $ClassId = $1;
- my $ClassName = $TypeDescr{$Version}{getTypeDeclId($ClassId)}{$ClassId}{"Name"};
- if($ClassName)
- {
- $FuncPtrCorrectName .= " ($ClassName\:\:*) (".join(", ", @ParamTypeName).")";
- }
- else
- {
- $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
- }
- }
- else
- {
- $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
- }
- }
- $TypeAttr{"Name"} = correctName($FuncPtrCorrectName);
- return %TypeAttr;
-}
-
-sub getTypeName($)
-{
- my $Info = $LibInfo{$Version}{$_[0]}{"info"};
- if($Info =~ /name[ ]*:[ ]*@([0-9]+) /)
- {
- return getNameByInfo($1);
- }
- else
- {
- if($LibInfo{$Version}{$_[0]}{"info_type"} eq "integer_type")
- {
- if($LibInfo{$Version}{$_[0]}{"info"} =~ /unsigned/)
- {
- return "unsigned int";
- }
- else
- {
- return "int";
- }
- }
- else
- {
- return "";
- }
- }
-}
-
-sub selectBaseType($$)
-{
- my ($TypeDeclId, $TypeId) = @_;
- my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
- my $BaseTypeDeclId;
- my $Type_Type = getTypeType($TypeDeclId, $TypeId);
- #qualifications
- if(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
- {
- return ($1, getTypeDeclId($1), "const");
- }
- elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
- {
- return ($1, getTypeDeclId($1), "restrict");
- }
- elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
- {
- return ($1, getTypeDeclId($1), "volatile");
- }
- elsif((not ($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:/)) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
- {#typedefs
- return ($1, getTypeDeclId($1), "");
- }
- elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "reference_type")
- {
- if($TypeInfo =~ /refd[ ]*:[ ]*@([0-9]+) /)
- {
- return ($1, getTypeDeclId($1), "&");
- }
- else
- {
- return (0, 0, "");
- }
- }
- elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "array_type")
- {
- if($TypeInfo =~ /elts[ ]*:[ ]*@([0-9]+) /)
- {
- return ($1, getTypeDeclId($1), "");
- }
- else
- {
- return (0, 0, "");
- }
- }
- elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "pointer_type")
- {
- if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+) /)
- {
- return ($1, getTypeDeclId($1), "*");
- }
- else
- {
- return (0, 0, "");
- }
- }
- else
- {
- return (0, 0, "");
- }
-}
-
-sub getFuncDescr_All()
-{
- foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
- {
- if($LibInfo{$Version}{$_}{"info_type"} eq "function_decl")
- {
- getFuncDescr($_);
- }
- }
-}
-
-sub getVarDescr_All()
-{
- foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
- {
- if($LibInfo{$Version}{$_}{"info_type"} eq "var_decl")
- {
- getVarDescr($_);
- }
- }
-}
-
-sub getVarDescr($)
-{
- my $FuncInfoId = $_[0];
- if($LibInfo{$Version}{getNameSpaceId($FuncInfoId)}{"info_type"} eq "function_decl")
- {
- return;
- }
- ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
- if((not $FuncDescr{$Version}{$FuncInfoId}{"Header"}) or ($FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/))
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getNameByInfo($FuncInfoId);
- $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
- if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"})
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Name"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
- $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
- }
- if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
- {
- delete $FuncDescr{$Version}{$FuncInfoId};
- return;
- }
- $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getTypeId($FuncInfoId);
- delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
- $FuncDescr{$Version}{$FuncInfoId}{"Data"} = 1;
- set_Class_And_Namespace($FuncInfoId);
- setFuncAccess($FuncInfoId);
- if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_ZTV/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
- }
- if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\A_Z/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
- }
-}
-
-sub getTrivialTypeAttr($$)
-{
- my ($TypeInfoId, $TypeId) = @_;
- my %TypeAttr = ();
- return if(getTypeTypeByTypeId($TypeId)!~/Intrinsic|Union|Struct|Enum/);
- setTypeAccess($TypeId, \%TypeAttr);
- ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeInfoId);
- if(($TypeAttr{"Header"} eq "<built-in>") or ($TypeAttr{"Header"} eq "<internal>"))
- {
- delete($TypeAttr{"Header"});
- }
- $TypeAttr{"Name"} = getNameByInfo($TypeInfoId);
- $TypeAttr{"Name"} = getTypeName($TypeId) if(not $TypeAttr{"Name"});
- my $NameSpaceId = getNameSpaceId($TypeInfoId);
- if($NameSpaceId ne $TypeId)
- {
- $TypeAttr{"NameSpace"} = getNameSpace($TypeInfoId);
- }
- if($TypeAttr{"NameSpace"} and isNotAnon($TypeAttr{"Name"}))
- {
- $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
- }
- $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
- if(isAnon($TypeAttr{"Name"}))
- {
- $TypeAttr{"Name"} = "anon-";
- $TypeAttr{"Name"} .= $TypeAttr{"Header"}."-".$TypeAttr{"Line"};
- }
- $TypeAttr{"Size"} = getSize($TypeId)/8;
- $TypeAttr{"Type"} = getTypeType($TypeInfoId, $TypeId);
- if($TypeAttr{"Type"} eq "Struct" and has_methods($TypeId))
- {
- $TypeAttr{"Type"} = "Class";
- }
- if(($TypeAttr{"Type"} eq "Struct") or ($TypeAttr{"Type"} eq "Class"))
- {
- setBaseClasses($TypeInfoId, $TypeId, \%TypeAttr);
- }
- setTypeMemb($TypeInfoId, $TypeId, \%TypeAttr);
- $TypeAttr{"Tid"} = $TypeId;
- $TypeAttr{"TDid"} = $TypeInfoId;
- $Tid_TDid{$Version}{$TypeId} = $TypeInfoId;
- if(not $TName_Tid{$Version}{$TypeAttr{"Name"}})
- {
- $TName_Tid{$Version}{$TypeAttr{"Name"}} = $TypeId;
- }
- return %TypeAttr;
-}
-
-sub has_methods($)
-{
- my $TypeId = $_[0];
- my $Info = $LibInfo{$Version}{$TypeId}{"info"};
- return ($Info=~/(fncs)[ ]*:[ ]*@([0-9]+) /);
-}
-
-sub setBaseClasses($$$)
-{
- my ($TypeInfoId, $TypeId, $TypeAttr) = @_;
- my $Info = $LibInfo{$Version}{$TypeId}{"info"};
- if($Info =~ /binf[ ]*:[ ]*@([0-9]+) /)
- {
- $Info = $LibInfo{$Version}{$1}{"info"};
- while($Info =~ /accs[ ]*:[ ]*([a-z]+) /)
- {
- last if($Info !~ s/accs[ ]*:[ ]*([a-z]+) //);
- my $Access = $1;
- last if($Info !~ s/binf[ ]*:[ ]*@([0-9]+) //);
- my $BInfoId = $1;
- my $ClassId = getBinfClassId($BInfoId);
- if($Access eq "pub")
- {
- $TypeAttr->{"BaseClass"}{$ClassId} = "public";
- }
- elsif($Access eq "prot")
- {
- $TypeAttr->{"BaseClass"}{$ClassId} = "protected";
- }
- elsif($Access eq "priv")
- {
- $TypeAttr->{"BaseClass"}{$ClassId} = "private";
- }
- else
- {
- $TypeAttr->{"BaseClass"}{$ClassId} = "private";
- }
- }
- }
-}
-
-sub getBinfClassId($)
-{
- my $Info = $LibInfo{$Version}{$_[0]}{"info"};
- $Info =~ /type[ ]*:[ ]*@([0-9]+) /;
- return $1;
-}
-
-sub get_func_signature($)
-{
- my $FuncInfoId = $_[0];
- my $PureSignature = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
- my @ParamTypes = ();
- foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$FuncDescr{$Version}{$FuncInfoId}{"Param"}}))
- {#checking parameters
- my $ParamType_Id = $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$ParamPos}{"type"};
- my $ParamType_Name = uncover_typedefs($TypeDescr{$Version}{getTypeDeclId($ParamType_Id)}{$ParamType_Id}{"Name"});
- @ParamTypes = (@ParamTypes, $ParamType_Name);
- }
- $PureSignature = $PureSignature."(".join(", ", @ParamTypes).")";
- $PureSignature = delete_keywords($PureSignature);
- return correctName($PureSignature);
-}
-
-sub delete_keywords($)
-{
- my $TypeName = $_[0];
- $TypeName =~ s/(\W|\A)(enum |struct |union |class )/$1/g;
- return $TypeName;
-}
-
-sub uncover_typedefs($)
-{
- my $TypeName = $_[0];
- return "" if(not $TypeName);
- return $Cache{"uncover_typedefs"}{$Version}{$TypeName} if(defined $Cache{"uncover_typedefs"}{$Version}{$TypeName});
- my ($TypeName_New, $TypeName_Pre) = (correctName($TypeName), "");
- while($TypeName_New ne $TypeName_Pre)
- {
- $TypeName_Pre = $TypeName_New;
- my $TypeName_Copy = $TypeName_New;
- my %Words = ();
- while($TypeName_Copy=~s/(\W|\A)([a-z_][\w:]*)(\W|\Z)//io)
- {
- my $Word = $2;
- next if(not $Word or $Word=~/\A(true|false|const|int|long|void|short|float|unsigned|char|double|class|struct|union|enum)\Z/);
- $Words{$Word} = 1;
- }
- foreach my $Word (keys(%Words))
- {
- my $BaseType_Name = $Typedef_BaseName{$Version}{$Word};
- next if($TypeName_New=~/(\W|\A)(struct $Word|union $Word|enum $Word)(\W|\Z)/);
- next if(not $BaseType_Name);
- if($BaseType_Name=~/\([*]+\)/)
- {
- $TypeName_New =~ /$Word(.*)\Z/;
- my $Type_Suffix = $1;
- $TypeName_New = $BaseType_Name;
- if($TypeName_New =~ s/\(([*]+)\)/($1 $Type_Suffix)/)
- {
- $TypeName_New = correctName($TypeName_New);
- }
- }
- else
- {
- if($TypeName_New =~ s/(\W|\A)$Word(\W|\Z)/$1$BaseType_Name$2/g)
- {
- $TypeName_New = correctName($TypeName_New);
- }
- }
- }
- }
- $Cache{"uncover_typedefs"}{$Version}{$TypeName} = $TypeName_New;
- return $TypeName_New;
-}
-
-sub isInternal($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- return 0 if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
- my $FuncMnglNameInfoId = $1;
- return ($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} =~ /\*[ ]*INTERNAL[ ]*\*/);
-}
-
-sub set_Class_And_Namespace($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
- {
- my $NameSpaceInfoId = $1;
- if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
- {
- my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
- if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
- {
- my $NameSpaceId = $1;
- my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
- if($NameSpaceIdentifier =~ /strg[ ]*:[ ]*(.*)[ ]+lngt/)
- {
- my $NameSpace = $1;
- $NameSpace =~ s/[ ]+\Z//g;
- $FuncDescr{$Version}{$FuncInfoId}{"NameSpace"} = $NameSpace;
- }
- }
- }
- elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Class"} = $NameSpaceInfoId;
- }
- }
-}
-
-sub getFuncDescr($)
-{
- my $FuncInfoId = $_[0];
- return if(isInternal($FuncInfoId));
- ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
- if(not $FuncDescr{$Version}{$FuncInfoId}{"Header"} or $FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- setFuncAccess($FuncInfoId);
- setFuncKind($FuncInfoId);
- if($FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"})
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- $FuncDescr{$Version}{$FuncInfoId}{"Type"} = getFuncType($FuncInfoId);
- $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getFuncReturn($FuncInfoId);
- delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
- $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getFuncShortName(getFuncOrig($FuncInfoId));
- if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\._/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- if(defined $TemplateInstance_Func{$Version}{$FuncInfoId})
- {
- my @TmplParams = ();
- foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$TemplateInstance_Func{$Version}{$FuncInfoId}}))
- {
- my $Param = get_TemplateParam($TemplateInstance_Func{$Version}{$FuncInfoId}{$ParamPos});
- if($Param eq "")
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- push(@TmplParams, $Param);
- }
- $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} .= "<".join(", ", @TmplParams).">";
- }
- setFuncParams($FuncInfoId);
- $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
- if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
-
- if((is_in_library($FuncDescr{$Version}{$FuncInfoId}{"ShortName"}, $Version) or $CheckHeadersOnly) and not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and ($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function"))
- {
- $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
- }
- set_Class_And_Namespace($FuncInfoId);
- if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and not $FuncDescr{$Version}{$FuncInfoId}{"Class"})
- {#this section only for c++ functions without class that have not been mangled in the tree
- $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $mangled_name{get_func_signature($FuncInfoId)};
- }
- if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
- {#src only
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- if($FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
- {
- delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
- }
- my $FuncBody = getFuncBody($FuncInfoId);
- if($FuncBody eq "defined")
- {
- $FuncDescr{$Version}{$FuncInfoId}{"InLine"} = 1;
- }
- if($CheckHeadersOnly and $FuncDescr{$Version}{$FuncInfoId}{"InLine"})
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- if(($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Method") or $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
- {
- if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
- {
- delete($FuncDescr{$Version}{$FuncInfoId});
- return;
- }
- }
- if(getFuncSpec($FuncInfoId) eq "Virt")
- {#virtual methods
- $FuncDescr{$Version}{$FuncInfoId}{"Virt"} = 1;
- }
- if(getFuncSpec($FuncInfoId) eq "PureVirt")
- {#pure virtual methods
- $FuncDescr{$Version}{$FuncInfoId}{"PureVirt"} = 1;
- }
- if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_Z/ and $FuncDescr{$Version}{$FuncInfoId}{"Class"})
- {
- if($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function")
- {#static methods
- $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
- }
- }
- if(getFuncLink($FuncInfoId) eq "Static")
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
- }
- delete($FuncDescr{$Version}{$FuncInfoId}{"Type"});
-}
-
-sub getFuncBody($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($FuncInfo =~ /body[ ]*:[ ]*undefined(\ |\Z)/i)
- {
- return "undefined";
- }
- elsif($FuncInfo =~ /body[ ]*:[ ]*@([0-9]+)(\ |\Z)/i)
- {
- return "defined";
- }
- else
- {
- return "";
- }
-}
-
-sub getTypeShortName($)
-{
- my $TypeName = $_[0];
- $TypeName =~ s/\<.*\>//g;
- $TypeName =~ s/.*\:\://g;
- return $TypeName;
-}
-
-sub getBackRef($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getTypeId($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getFuncId($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub setTypeMemb($$)
-{
- my ($TypeDeclId, $TypeId, $TypeAttr) = @_;
- my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
- my $TypeMembInfoId;
- my $TypeType = $TypeAttr->{"Type"};
- my $Position = 0;
- my $BasePosition = 0;
- my $TypeTypeInfoId;
- my $StructMembName;
- if($TypeType eq "Enum")
- {
- $TypeMembInfoId = getEnumMembInfoId($TypeId);
- while($TypeMembInfoId)
- {
- $TypeAttr->{"Memb"}{$Position}{"value"} = getEnumMembVal($TypeMembInfoId);
- my $MembName = getEnumMembName($TypeMembInfoId);
- $TypeAttr->{"Memb"}{$Position}{"name"} = getEnumMembName($TypeMembInfoId);
- $EnumMembName_Id{$Version}{getTreeAttr($TypeMembInfoId, "valu")} = ($TypeAttr->{"NameSpace"})?$TypeAttr->{"NameSpace"}."::".$MembName:$MembName;
- $TypeMembInfoId = getNextMembInfoId($TypeMembInfoId);
- $Position += 1;
- }
- }
- elsif(($TypeType eq "Struct") or ($TypeType eq "Class") or ($TypeType eq "Union"))
- {
- $TypeMembInfoId = getStructMembInfoId($TypeId);
- while($TypeMembInfoId)
- {
- if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} ne "field_decl")
- {
- $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
- next;
- }
- $StructMembName = getStructMembName($TypeMembInfoId);
- if($StructMembName =~ /_vptr\./)
- {#virtual tables
- $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
- next;
- }
- if(not $StructMembName)
- {#base classes
- #$TypeAttr->{"Base"}{$BasePosition}{"type"} = getStructMembType($TypeMembInfoId);
- #$TypeAttr->{"Base"}{$BasePosition}{"access"} = getStructMembAccess($TypeMembInfoId);
- $BasePosition += 1;
- $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
- next;
- }
- $TypeAttr->{"Memb"}{$Position}{"type"} = getStructMembType($TypeMembInfoId);
- $TypeAttr->{"Memb"}{$Position}{"name"} = $StructMembName;
- $TypeAttr->{"Memb"}{$Position}{"access"} = getStructMembAccess($TypeMembInfoId);
- $TypeAttr->{"Memb"}{$Position}{"bitfield"} = getStructMembBitFieldSize($TypeMembInfoId);
-
- $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
- $Position += 1;
- }
- }
-}
-
-sub setFuncParams($)
-{
- my $FuncInfoId = $_[0];
- my $ParamInfoId = getFuncParamInfoId($FuncInfoId);
- my $FunctionType = getFuncType($FuncInfoId);
- if($FunctionType eq "Method")
- {
- $ParamInfoId = getNextElem($ParamInfoId);
- }
- my $Position = 0;
- while($ParamInfoId)
- {
- my $ParamTypeId = getFuncParamType($ParamInfoId);
- last if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void");
- if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Type"} eq "Restrict")
- {#delete restrict spec
- $ParamTypeId = getRestrictBase($ParamTypeId);
- }
- $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = $ParamTypeId;
- $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = getFuncParamName($ParamInfoId);
- if(not $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"})
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = "p".($Position+1);
- }
- $ParamInfoId = getNextElem($ParamInfoId);
- $Position += 1;
- }
- if(detect_nolimit_args($FuncInfoId))
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = -1;
- }
-}
-
-sub detect_nolimit_args($)
-{
- my $FuncInfoId = $_[0];
- my $FuncTypeId = getFuncTypeId($FuncInfoId);
- my $ParamListElemId = getFuncParamTreeListId($FuncTypeId);
- my $HaveVoid = 0;
- my $Position = 0;
- while($ParamListElemId)
- {
- my $ParamTypeId = getTreeAttr($ParamListElemId, "valu");
- if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void")
- {
- $HaveVoid = 1;
- last;
- }
- $ParamListElemId = getNextElem($ParamListElemId);
- $Position += 1;
- }
- return ($Position>=1 and not $HaveVoid);
-}
-
-sub getFuncParamTreeListId($)
-{
- my $FuncTypeId = $_[0];
- if($LibInfo{$Version}{$FuncTypeId}{"info"} =~ /prms[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getTreeAttr($$)
-{
- my ($Id, $Attr) = @_;
- if($LibInfo{$Version}{$Id}{"info"} =~ /$Attr[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getRestrictBase($)
-{
- my $TypeId = $_[0];
- my $TypeDeclId = getTypeDeclId($TypeId);
- my $BaseTypeId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"Tid"};
- my $BaseTypeDeclId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"TDid"};
- return $BaseTypeId;
-}
-
-sub setFuncAccess($)
-{
- my $FuncInfoId = $_[0];
- if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
- {
- my $Access = $1;
- if($Access eq "prot")
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Protected"} = 1;
- }
- elsif($Access eq "priv")
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Private"} = 1;
- }
- }
-}
-
-sub setTypeAccess($$)
-{
- my ($TypeId, $TypeAttr) = @_;
- my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
- if($TypeInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
- {
- my $Access = $1;
- if($Access eq "prot")
- {
- $TypeAttr->{"Protected"} = 1;
- }
- elsif($Access eq "priv")
- {
- $TypeAttr->{"Private"} = 1;
- }
- }
-}
-
-sub setFuncKind($)
-{
- my $FuncInfoId = $_[0];
- if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /pseudo tmpl/)
- {
- $FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"} = 1;
- }
- elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*constructor /)
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} = 1;
- }
- elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*destructor /)
- {
- $FuncDescr{$Version}{$FuncInfoId}{"Destructor"} = 1;
- }
-}
-
-sub getFuncSpec($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ m/spec[ ]*:[ ]*pure /)
- {
- return "PureVirt";
- }
- elsif($FuncInfo =~ m/spec[ ]*:[ ]*virt /)
- {
- return "Virt";
- }
- else
- {
- if($FuncInfo =~ /spec[ ]*:[ ]*([a-zA-Z]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
- }
-}
-
-sub getFuncClass($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getFuncLink($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ /link[ ]*:[ ]*static /)
- {
- return "Static";
- }
- else
- {
- if($FuncInfo =~ /link[ ]*:[ ]*([a-zA-Z]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
- }
-}
-
-sub getNextElem($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ /chan[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getFuncParamInfoId($)
-{
- my $FuncInfoId = $_[0];
- my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
- if($FuncInfo =~ /args[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getFuncParamType($)
-{
- my $ParamInfoId = $_[0];
- my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
- if($ParamInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getFuncParamName($)
-{
- my $ParamInfoId = $_[0];
- my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
- return "" if($ParamInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
- my $NameInfoId = $1;
- return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
- my $FuncParamName = $1;
- $FuncParamName =~ s/[ ]+\Z//g;
- return $FuncParamName;
-}
-
-sub getEnumMembInfoId($)
-{
- my $TypeInfoId = $_[0];
- my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
- if($TypeInfo =~ /csts[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getStructMembInfoId($)
-{
- my $TypeInfoId = $_[0];
- my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
- if($TypeInfo =~ /flds[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getNameSpace($)
-{
- my $TypeInfoId = $_[0];
- my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
- return "" if($TypeInfo !~ /scpe[ ]*:[ ]*@([0-9]+) /);
- my $NameSpaceInfoId = $1;
- if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
- {
- my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
- if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
- {
- my $NameSpaceId = $1;
- my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
- return "" if($NameSpaceIdentifier !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
- my $NameSpace = $1;
- $NameSpace =~ s/[ ]+\Z//g;
- my $BaseNameSpace = getNameSpace($NameSpaceInfoId);
- $NameSpace = $BaseNameSpace."::".$NameSpace if($BaseNameSpace);
- return $NameSpace;
- }
- else
- {
- return "";
- }
- }
- elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
- {
- my %NameSpaceAttr = getTypeAttr(getTypeDeclId($NameSpaceInfoId), $NameSpaceInfoId);
- return $NameSpaceAttr{"Name"};
- }
- else
- {
- return "";
- }
-}
-
-sub getNameSpaceId($)
-{
- my $TypeInfoId = $_[0];
- my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
- if($TypeInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getEnumMembName($)
-{
- my $TypeMembInfoId = $_[0];
- return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /purp[ ]*:[ ]*@([0-9]+)/);
- my $Purp = $1;
- return "" if($LibInfo{$Version}{$Purp}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
- my $EnumMembName = $1;
- $EnumMembName =~ s/[ ]+\Z//g;
- return $EnumMembName;
-}
-
-sub getStructMembName($)
-{
- my $TypeMembInfoId = $_[0];
- return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /name[ ]*:[ ]*@([0-9]+) /);
- my $NameInfoId = $1;
- return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
- my $StructMembName = $1;
- $StructMembName =~ s/[ ]+\Z//g;
- return $StructMembName;
-}
-
-sub getEnumMembVal($)
-{
- my $TypeMembInfoId = $_[0];
- return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /valu[ ]*:[ ]*@([0-9]+) /);
- my $Valu = $1;
- if($LibInfo{$Version}{$Valu}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getSize($)
-{
- my $Info = $LibInfo{$Version}{$_[0]}{"info"};
- if($Info =~ /size[ ]*:[ ]*@([0-9]+) /)
- {
- my $SizeInfoId = $1;
- if($LibInfo{$Version}{$SizeInfoId}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
- }
- else
- {
- return 0;
- }
-}
-
-sub getStructMembType($)
-{
- my $TypeMembInfoId = $_[0];
- if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /type[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getStructMembBitFieldSize($)
-{
- my $TypeMembInfoId = $_[0];
- if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ / bitfield /)
- {
- return getSize($TypeMembInfoId);
- }
- else
- {
- return 0;
- }
-}
-
-sub getStructMembAccess($)
-{
- my $MembInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($MembInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
- {
- my $Access = $1;
- if($Access eq "prot")
- {
- return "protected";
- }
- elsif($Access eq "priv")
- {
- return "private";
- }
- else
- {
- return "public";
- }
- }
- else
- {
- return "public";
- }
-}
-
-sub getNextMembInfoId($)
-{
- my $TypeMembInfoId = $_[0];
- if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getNextStructMembInfoId($)
-{
- my $TypeMembInfoId = $_[0];
- if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub fieldHasName($)
-{
- my $TypeMembInfoId = $_[0];
- if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} eq "field_decl")
- {
- if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /name[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
- }
- else
- {
- return 0;
- }
-}
-
-sub getTypeHeader($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
- {
- return ($1, $2);
- }
- else
- {
- return ();
- }
-}
-
-sub register_header($$$)
-{
- my ($Destination, $Position, $LibVersion) = @_;
- return if(not $Destination);
- if($Destination=~/\A\// and not -f $Destination)
- {
- print "\nERROR: specified header \'$Destination\' does not exist\n";
- return;
- }
- my $Header_Name = get_FileName($Destination);
- $Headers{$LibVersion}{$Destination}{"Name"} = $Header_Name;
- $Headers{$LibVersion}{$Destination}{"Position"} = $Position;
- $Headers{$LibVersion}{$Destination}{"Identity"} = $Destination;
- $HeaderName_Destinations{$LibVersion}{$Header_Name}{$Destination} = 1;
-}
-
-sub headerSearch($)
-{
- my $LibVersion = $_[0];
- foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Include_Paths"}))
- {
- $Dest =~ s/\A\s+|\s+\Z//g;
- next if(not $Dest);
- if(not -e $Dest)
- {
- print "ERROR: can't access \'$Dest\'\n";
- }
- $Header_Dependency{$LibVersion}{$Dest} = 1;
- }
- foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
- {#fill %Header_Dependency
- if(-d $Dest)
- {
- foreach my $Dir (cmd_find($Dest,"d",""))
- {
- chomp($Dir);
- $Header_Dependency{$LibVersion}{$Dir} = 1;
- }
- }
- elsif(-f $Dest)
- {
- $Header_Dependency{$LibVersion}{get_Dir($Dest)} = 1;
- }
- }
- my $Position = 0;
- foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
- {
- $Dest =~ s/\A\s+|\s+\Z//g;
- next if(not $Dest);
- if(is_header($Dest, $LibVersion))
- {
- register_header($Dest, $Position, $LibVersion);
- $Position += 1;
- }
- elsif(-d $Dest)
- {
- foreach my $Destination (sort {lc($a) cmp lc($b)} (cmd_find($Dest,"f","")))
- {
- chomp($Destination);
- next if(not is_header($Destination, $LibVersion));
- register_header($Destination, $Position, $LibVersion);
- $Position += 1;
- }
- }
- else
- {
- print "WARNING: \'$Dest\' was not found in the specified include paths\n";
- register_header($Dest, $Position, $LibVersion);
- $Position += 1;
- }
- }
- if(keys(%{$Headers{$LibVersion}})==1)
- {
- my $Destination = (keys(%{$Headers{$LibVersion}}))[0];
- $Headers{$LibVersion}{$Destination}{"Identity"} = $Headers{$LibVersion}{$Destination}{"Name"};
- }
- foreach my $Header_Name (keys(%{$HeaderName_Destinations{$LibVersion}}))
- {#set relative paths (for dublicates)
- if(keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}})>1)
- {
- my $FirstDest = (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))[0];
- my $Prefix = get_Dir($FirstDest);
- while($Prefix =~ /\A(.+)\/[^\/]+\Z/)
- {
- my $NewPrefix = $1;
- my $Changes_Number = 0;
- my %Identity = ();
- foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
- {
- if($Dest =~ /\A$Prefix\/(.*)\Z/)
- {
- $Identity{$Dest} = $1;
- $Changes_Number+=1;
- }
- }
- if($Changes_Number eq keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
- {
- foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
- {
- $Headers{$LibVersion}{$Dest}{"Identity"} = $Identity{$Dest};
- }
- last;
- }
- $Prefix = $NewPrefix;
- }
- }
- }
- if(not keys(%{$Headers{$LibVersion}}))
- {
- print "ERROR: header files were not found\n";
- exit(1);
- }
-}
-
-sub get_FileName($)
-{
- my $Path = $_[0];
- if($Path =~ /\A(.*\/)([^\/]*)\Z/)
- {
- return $2;
- }
- else
- {
- return $Path;
- }
-}
-
-sub get_Dir($)
-{
- my $Path = $_[0];
- return "" if($Path =~ m*\A\./*);
- if($Path =~ /\A(.*)\/([^\/]*)\Z/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub esc($)
-{
- my $Str = $_[0];
- $Str =~ s/([()\[\]{}$ &'"`;,<>])/\\$1/g;
- return $Str;
-}
-
-sub getLocation($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
- {
- return ($1, $2);
- }
- else
- {
- return ();
- }
-}
-
-sub getHeader($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-sub getLine($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
- {
- return $2;
- }
- else
- {
- return "";
- }
-}
-
-sub getTypeType($$)
-{
- my ($TypeDeclId, $TypeId) = @_;
- return "Const" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
- return "Typedef" if($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:/ and $LibInfo{$Version}{$TypeId}{"info"} !~ /qual[ ]*:/);
- return "Volatile" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
- return "Restrict" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
- my $TypeType = getTypeTypeByTypeId($TypeId);
- if($TypeType eq "Struct")
- {
- if($TypeDeclId and $LibInfo{$Version}{$TypeDeclId}{"info_type"} eq "template_decl")
- {
- return "Template";
- }
- else
- {
- return "Struct";
- }
- }
- else
- {
- return $TypeType;
- }
-
-}
-
-sub getTypeTypeByTypeId($)
-{
- my $TypeId = $_[0];
- my $TypeType = $LibInfo{$Version}{$TypeId}{"info_type"};
- if($TypeType =~ /integer_type|real_type|boolean_type|void_type|complex_type/)
- {
- return "Intrinsic";
- }
- elsif(isFuncPtr($TypeId))
- {
- return "FuncPtr";
- }
- elsif($TypeType eq "pointer_type")
- {
- return "Pointer";
- }
- elsif($TypeType eq "reference_type")
- {
- return "Ref";
- }
- elsif($TypeType eq "union_type")
- {
- return "Union";
- }
- elsif($TypeType eq "enumeral_type")
- {
- return "Enum";
- }
- elsif($TypeType eq "record_type")
- {
- return "Struct";
- }
- elsif($TypeType eq "array_type")
- {
- return "Array";
- }
- elsif($TypeType eq "complex_type")
- {
- return "Intrinsic";
- }
- elsif($TypeType eq "function_type")
- {
- return "FunctionType";
- }
- elsif($TypeType eq "method_type")
- {
- return "MethodType";
- }
- else
- {
- return "Unknown";
- }
-}
-
-sub getNameByInfo($)
-{
- my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
- return "" if($TypeInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
- my $TypeNameInfoId = $1;
- return "" if($LibInfo{$Version}{$TypeNameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
- my $TypeName = $1;
- $TypeName =~ s/[ ]+\Z//g;
- return $TypeName;
-}
-
-sub getFuncShortName($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($FuncInfo =~ / operator /)
- {
- if($FuncInfo =~ /note[ ]*:[ ]*conversion /)
- {
- return "operator ".get_TypeName($FuncDescr{$Version}{$_[0]}{"Return"});
- }
- else
- {
- return "" if($FuncInfo !~ / operator[ ]+([a-zA-Z]+) /);
- return "operator".$Operator_Indication{$1};
- }
- }
- else
- {
- return "" if($FuncInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
- my $FuncNameInfoId = $1;
- return "" if($LibInfo{$Version}{$FuncNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+lngt/);
- return $1;
- }
-}
-
-sub getFuncMnglName($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- return "" if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
- my $FuncMnglNameInfoId = $1;
- return "" if($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+/);
- my $FuncMnglName = $1;
- $FuncMnglName =~ s/[ ]+\Z//g;
- return $FuncMnglName;
-}
-
-sub getFuncReturn($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
- my $FuncTypeInfoId = $1;
- return "" if($LibInfo{$Version}{$FuncTypeInfoId}{"info"} !~ /retn[ ]*:[ ]*@([0-9]+) /);
- my $FuncReturnTypeId = $1;
- if($TypeDescr{$Version}{getTypeDeclId($FuncReturnTypeId)}{$FuncReturnTypeId}{"Type"} eq "Restrict")
- {#delete restrict spec
- $FuncReturnTypeId = getRestrictBase($FuncReturnTypeId);
- }
- return $FuncReturnTypeId;
-}
-
-sub getFuncOrig($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($FuncInfo =~ /orig[ ]*:[ ]*@([0-9]+) /)
- {
- return $1;
- }
- else
- {
- return $_[0];
- }
-}
-
-sub unmangleArray(@)
-{
- if($#_>$MAX_COMMAND_LINE_ARGUMENTS)
- {
- my @Half = splice(@_, 0, ($#_+1)/2);
- return (unmangleArray(@Half), unmangleArray(@_))
- }
- else
- {
- my $UnmangleCommand = "c++filt ".join(" ", @_);
- return split("\n", `$UnmangleCommand`);
- }
-}
-
-sub get_Signature($$)
-{
- my ($Interface, $LibVersion) = @_;
- return $Cache{"get_Signature"}{$Interface}{$LibVersion} if($Cache{"get_Signature"}{$Interface}{$LibVersion});
- my ($MnglName, $SymbolVersion) = ($Interface, "");
- if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
- {
- ($MnglName, $SymbolVersion) = ($1, $2);
- }
- if($MnglName =~ /\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZThn|_ZTv0_n)/)
- {
- $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
- return $Cache{"get_Signature"}{$Interface}{$LibVersion};
- }
- if(not $CompleteSignature{$LibVersion}{$Interface})
- {
- if($Interface =~ /\A_Z/)
- {
- $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
- return $Cache{"get_Signature"}{$Interface}{$LibVersion};
- }
- else
- {
- $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Interface;
- return $Interface;
- }
- }
- my ($Func_Signature, @Param_Types_FromUnmangledName) = ();
- my $ShortName = $CompleteSignature{$LibVersion}{$Interface}{"ShortName"};
- if($Interface =~ /\A_Z/)
- {
- if($CompleteSignature{$LibVersion}{$Interface}{"Class"})
- {
- $Func_Signature = get_TypeName($CompleteSignature{$LibVersion}{$Interface}{"Class"}, $LibVersion)."::".(($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})?"~":"").$ShortName;
- }
- else
- {
- $Func_Signature = $ShortName;
- }
- @Param_Types_FromUnmangledName = get_Signature_Parts($tr_name{$MnglName}, 0);
- }
- else
- {
- $Func_Signature = $MnglName;
- }
- my @ParamArray = ();
- foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Interface}{"Param"}}))
- {
- next if($Pos eq "");
- my $ParamTypeId = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"type"};
- my $ParamTypeName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ParamTypeId}}{$ParamTypeId}{"Name"};
- $ParamTypeName = $Param_Types_FromUnmangledName[$Pos] if(not $ParamTypeName);
- if(my $ParamName = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"name"})
- {
- if($ParamTypeName=~/\([*]+\)/)
- {
- $ParamTypeName=~s/\(([*]+)\)/\($1$ParamName\)/;
- push(@ParamArray, $ParamTypeName);
- }
- else
- {
- push(@ParamArray, $ParamTypeName." ".$ParamName);
- }
- }
- else
- {
- push(@ParamArray, $ParamTypeName);
- }
- }
- if(not $CompleteSignature{$LibVersion}{$Interface}{"Data"})
- {
- if($Interface=~/\A_Z/)
- {
- if($CompleteSignature{$LibVersion}{$Interface}{"Constructor"})
- {
- if($Interface=~/C1/)
- {
- $Func_Signature .= " [in-charge]";
- }
- elsif($Interface=~/C2/)
- {
- $Func_Signature .= " [not-in-charge]";
- }
- }
- elsif($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})
- {
- if($Interface=~/D1/)
- {
- $Func_Signature .= " [in-charge]";
- }
- elsif($Interface=~/D2/)
- {
- $Func_Signature .= " [not-in-charge]";
- }
- elsif($Interface=~/D0/)
- {
- $Func_Signature .= " [in-charge-deleting]";
- }
- }
- }
- $Func_Signature .= " (".join(", ", @ParamArray).")";
- }
- if($Interface=~/\A_ZNK/)
- {
- $Func_Signature .= " const";
- }
- $Func_Signature .= "\@".$SymbolVersion if($SymbolVersion);
- $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Func_Signature;
- return $Func_Signature;
-}
-
-sub getVarNameByAttr($)
-{
- my $FuncInfoId = $_[0];
- my $VarName;
- return "" if(not $FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
- if($FuncDescr{$Version}{$FuncInfoId}{"Class"})
- {
- $VarName .= $TypeDescr{$Version}{getTypeDeclId($FuncDescr{$Version}{$FuncInfoId}{"Class"})}{$FuncDescr{$Version}{$FuncInfoId}{"Class"}}{"Name"};
- $VarName .= "::";
- }
- $VarName .= $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
- return $VarName;
-}
-
-sub mangleFuncName($)
-{
- my $FuncId = $_[0];
-}
-
-sub getFuncType($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
- my $FuncTypeInfoId = $1;
- my $FunctionType = $LibInfo{$Version}{$FuncTypeInfoId}{"info_type"};
- if($FunctionType eq "method_type")
- {
- return "Method";
- }
- elsif($FunctionType eq "function_type")
- {
- return "Function";
- }
- else
- {
- return $FunctionType;
- }
-}
-
-sub getFuncTypeId($)
-{
- my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
- if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+)( |\Z)/)
- {
- return $1;
- }
- else
- {
- return 0;
- }
-}
-
-sub isNotAnon($)
-{
- return (not isAnon($_[0]));
-}
-
-sub isAnon($)
-{
- return (($_[0] =~ m/\.\_[0-9]+/) or ($_[0] =~ m/anon-/));
-}
-
-sub unmangled_Compact($$)
-#Removes all non-essential (for C++ language) whitespace from a string. If
-#the whitespace is essential it will be replaced with exactly one ' '
-#character. Works correctly only for unmangled names.
-#If level > 1 is supplied, can relax its intent to compact the string.
-{
- my $result=$_[0];
- my $level = $_[1] || 1;
- my $o1 = ($level>1)?' ':'';
- #First, we reduce all spaces that we can
- my $coms='[-()<>:*&~!|+=%@~"?.,/[^'."']";
- my $coms_nobr='[-()<:*&~!|+=%@~"?.,'."']";
- my $clos='[),;:\]]';
- $result=~s/^\s+//gm;
- $result=~s/\s+$//gm;
- $result=~s/((?!\n)\s)+/ /g;
- $result=~s/(\w+)\s+($coms+)/$1$o1$2/gm;
- #$result=~s/(\w)(\()/$1$o1$2/gm if $o1;
- $result=~s/($coms+)\s+(\w+)/$1$o1$2/gm;
- $result=~s/(\()\s+(\w)/$1$2/gm if $o1;
- $result=~s/(\w)\s+($clos)/$1$2/gm;
- $result=~s/($coms+)\s+($coms+)/$1 $2/gm;
- $result=~s/($coms_nobr+)\s+($coms+)/$1$o1$2/gm;
- $result=~s/($coms+)\s+($coms_nobr+)/$1$o1$2/gm;
- #don't forget about >> and <:. In unmangled names global-scope modifier
- #is not used, so <: will always be a digraph and requires no special treatment.
- #We also try to remove other parts that are better to be removed here than in other places
- #double-cv
- $result=~s/\bconst\s+const\b/const/gm;
- $result=~s/\bvolatile\s+volatile\b/volatile/gm;
- $result=~s/\bconst\s+volatile\b\s+const\b/const volatile/gm;
- $result=~s/\bvolatile\s+const\b\s+volatile\b/const volatile/gm;
- #Place cv in proper order
- $result=~s/\bvolatile\s+const\b/const volatile/gm;
- return $result;
-}
-
-sub unmangled_PostProcess($)
-{
- my $result = $_[0];
- #s/\bunsigned int\b/unsigned/g;
- $result =~ s/\bshort unsigned int\b/unsigned short/g;
- $result =~ s/\bshort int\b/short/g;
- $result =~ s/\blong long unsigned int\b/unsigned long long/g;
- $result =~ s/\blong unsigned int\b/unsigned long/g;
- $result =~ s/\blong long int\b/long long/g;
- $result =~ s/\blong int\b/long/g;
- $result =~ s/\)const\b/\) const/g;
- $result =~ s/\blong long unsigned\b/unsigned long long/g;
- $result =~ s/\blong unsigned\b/unsigned long/g;
- return $result;
-}
-
-# From libtodb2/libtodb.pm
-# Trim string spaces.
-sub trim($)
-{
- my $string = shift;
- $string =~ s/^\s+//;
- $string =~ s/\s+$//;
- return $string;
-}
-
-sub correctName($)
-{#type name correction
- my $CorrectName = $_[0];
- $CorrectName = unmangled_Compact($CorrectName, 1);
- $CorrectName = unmangled_PostProcess($CorrectName);
- return $CorrectName;
-}
-
-sub getDump_AllInOne()
-{
- return if(not keys(%Headers));
- `mkdir -p temp && rm -f temp/*`;
- my $Header_Depend = "";
- foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
- {
- $Header_Depend .= " -I".esc($Dep);
- }
- my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
- open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
- foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
- {
- print LIB_HEADER "#include <$Preamble_Header>\n";
- }
- foreach my $Destination (sort {int($Headers{$Version}{$a}{"Position"})<=>int($Headers{$Version}{$b}{"Position"})} keys(%{$Headers{$Version}}))
- {
- my $HName = get_FileName($Destination);
- next if($Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$HName} and $HeaderName_Destinations{$Version}{$HName} and keys(%{$HeaderName_Destinations{$Version}{$HName}})==1));
- print LIB_HEADER "#include <$Destination>\n";
- }
- close(LIB_HEADER);
- system("g++ >".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
- if($?)
- {
- 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";
- }
- $ConstantsSrc{$Version} = cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
- system("mkdir", "-p", "header_compile_errors/$TargetLibraryName/temp/");
- system("cp", "-f", "temp/$TargetLibraryName"."_v$Version.h", "header_compile_errors/$TargetLibraryName/temp/");
- return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
-}
-
-sub getDump_Separately($)
-{
- `mkdir -p temp`;
- `rm -f temp/*`;
- my $Destination = $_[0];
- my $Header_Depend = "";
- foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
- {
- $Header_Depend .= " -I".esc($Dep);
- }
- my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
- open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
- foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
- {
- print LIB_HEADER "#include <$Preamble_Header>\n";
- }
- my $Destination_HName = get_FileName($Destination);
- 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) ))
- {
- print LIB_HEADER "#include <$Destination>\n";
- }
- close(LIB_HEADER);
- system("g++ >>".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
- if($?)
- {
- $HeaderCompileError{get_FileName($Destination)} = 1;
- }
- $ConstantsSrc{$Version} .= cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
- return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
-}
-
-sub cmd_file($)
-{
- my $Path = $_[0];
- return "" if(not $Path or not -e $Path);
- my $Cmd = "file ".esc($Path);
- my $Cmd_Out = `$Cmd`;
- return $Cmd_Out;
-}
-
-sub cmd_preprocessor($$$)
-{
- my ($Path, $AddOpt, $Grep) = @_;
- return "" if(not $Path or not -f $Path);
- my $Cmd = "g++ -dD -E -x c++-header ".esc($Path)." 2>/dev/null $AddOpt";
- if($Grep)
- {
- $Cmd .= " | grep \"$Grep\"";
- }
- my $Cmd_Out = `$Cmd`;
- return $Cmd_Out;
-}
-
-sub cmd_cat($$)
-{
- my ($Path, $Grep) = @_;
- return "" if(not $Path or not -e $Path);
- my $Cmd = "cat ".esc($Path);
- if($Grep)
- {
- $Cmd .= " | grep \"$Grep\"";
- }
- my $Cmd_Out = `$Cmd`;
- return $Cmd_Out;
-}
-
-sub cmd_find($$$)
-{
- my ($Path, $Type, $Name) = @_;
- return () if(not $Path or not -e $Path);
- my $Cmd = "find ".esc($Path);
- if($Type)
- {
- $Cmd .= " -type $Type";
- }
- if($Name)
- {
- $Cmd .= " -name \"$Name\"";
- }
- return split("\n", `$Cmd`);
-}
-
-sub cmd_tar($)
-{
- my $Path = $_[0];
- return "" if(not $Path or not -e $Path);
- my $Cmd = "tar -xvzf ".esc($Path);
- my $Cmd_Out = `$Cmd`;
- return $Cmd_Out;
-}
-
-sub is_header($$)
-{
- my ($Destination, $LibVersion) = @_;
- return 0 if(-d $Destination);
- return 1 if($Destination =~ /\.(h|hh|hhh|hpp|tcc)\Z/i);
- return 0 if($Destination =~ /\.\w+\Z/i);#cpp|c|gch|tu|fs|pas
- if($Destination =~ /\A\//)
- {
- return (cmd_file($Destination) =~ /:[ ]*ASCII C[\+]* program text/);
- }
- else
- {
- foreach my $Prefix (keys(%{$Header_Dependency{$LibVersion}}))
- {
- my $Path = $Prefix."/".$Destination;
- if(-f $Path)
- {
- if(cmd_file($Path) =~ /:[ ]*ASCII C[\+]* program text/)
- {
- return 1;
- }
- }
- }
- return 0;
- }
-}
-
-sub parseHeaders_AllInOne($)
-{
- $Version = $_[0];
- print "checking header(s) ".$Descriptor{$Version}{"Version"}." ...\n";
- system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
- system("rm", "-fr", $ERR_PATH{$Version});
- my $DumpPath = getDump_AllInOne();
- if(not $DumpPath)
- {
- print "\nERROR: can't create gcc syntax tree for header(s)\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
- exit(1);
- }
- getInfo($DumpPath);
- parse_constants();
- system("rm", "-fr", "temp");
-}
-
-sub parseHeader($)
-{
- my $Destination = $_[0];
- my $DumpPath = getDump_Separately($Destination);
- if(not $DumpPath)
- {
- print "ERROR: can't create gcc syntax tree for header\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
- exit(1);
- }
- getInfo($DumpPath);
- parse_constants();
- system("rm", "-fr", "temp");
-}
-
-sub is_in_library($$)
-{
- my ($MnglName, $LibVersion) = @_;
- return ($Interface_Library{$LibVersion}{$MnglName} or ($SymVer{$LibVersion}{$MnglName} and $Interface_Library{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}));
-}
-
-sub prepareInterfaces($)
-{
- my $LibVersion = $_[0];
- my (@MnglNames, @UnMnglNames) = ();
- if($CheckHeadersOnly)
- {
- foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
- {
- if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
- {
- push(@MnglNames, $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"});
- }
- }
- if($#MnglNames > -1)
- {
- @UnMnglNames = reverse(unmangleArray(@MnglNames));
- foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
- {
- if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
- {
- my $UnmangledName = pop(@UnMnglNames);
- $tr_name{$FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"}} = $UnmangledName;
- }
- }
- }
- }
- my (%NotMangled_Int, %Mangled_Int) = ();
- foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
- {
- my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
- if($MnglName=~/\A_Z/)
- {
- $Mangled_Int{$FuncInfoId} = $MnglName;
- }
- else
- {
- $NotMangled_Int{$FuncInfoId} = $MnglName;
- }
- next if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly);
- next if($MnglName =~ /\A_Z/ and $tr_name{$MnglName} =~ /\.\_[0-9]/);
- next if(not $FuncDescr{$LibVersion}{$FuncInfoId}{"Header"});
- %{$CompleteSignature{$LibVersion}{$MnglName}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
- #interface and its symlink have same signatures
- if($SymVer{$LibVersion}{$MnglName})
- {
- %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
- }
- delete($FuncDescr{$LibVersion}{$FuncInfoId});
- }
- if(keys(%Mangled_Int))
- {
- foreach my $Interface_Id (keys(%NotMangled_Int))
- {
- delete($CompleteSignature{$LibVersion}{$NotMangled_Int{$Interface_Id}});
- }
- }
-}
-
-my %UsedType;
-sub cleanData($)
-{
- my $LibVersion = $_[0];
- foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
- {
- my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
- if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly)
- {
- delete($FuncDescr{$LibVersion}{$FuncInfoId});
- next;
- }
- if(defined $InterfacesListPath and not $InterfacesList{$MnglName})
- {
- delete($FuncDescr{$LibVersion}{$FuncInfoId});
- next;
- }
- if(defined $AppPath and not $InterfacesList_App{$MnglName})
- {
- delete($FuncDescr{$LibVersion}{$FuncInfoId});
- next;
- }
- my %FuncInfo = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
- detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Return"}}, $FuncInfo{"Return"}, $LibVersion);
- detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Class"}}, $FuncInfo{"Class"}, $LibVersion);
- foreach my $Param_Pos (keys(%{$FuncInfo{"Param"}}))
- {
- my $Param_TypeId = $FuncInfo{"Param"}{$Param_Pos}{"type"};
- detect_TypeUsing($Tid_TDid{$LibVersion}{$Param_TypeId}, $Param_TypeId, $LibVersion);
- }
- }
- foreach my $TDid (keys(%{$TypeDescr{$LibVersion}}))
- {
- foreach my $Tid (keys(%{$TypeDescr{$LibVersion}{$TDid}}))
- {
- if(not $UsedType{$LibVersion}{$TDid}{$Tid})
- {
- delete($TypeDescr{$LibVersion}{$TDid}{$Tid});
- if(not keys(%{$TypeDescr{$LibVersion}{$TDid}}))
- {
- delete($TypeDescr{$LibVersion}{$TDid});
- }
- delete($Tid_TDid{$LibVersion}{$Tid}) if($Tid_TDid{$LibVersion}{$Tid} eq $TDid);
- }
- }
- }
-}
-
-sub detect_TypeUsing($$$)
-{
- my ($TypeDeclId, $TypeId, $LibVersion) = @_;
- return if($UsedType{$LibVersion}{$TypeDeclId}{$TypeId});
- my %Type = get_Type($TypeDeclId, $TypeId, $LibVersion);
- if($Type{"Type"} =~ /Struct|Union|Class|FuncPtr|Enum/)
- {
- $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
- foreach my $Memb_Pos (keys(%{$Type{"Memb"}}))
- {
- my $Member_TypeId = $Type{"Memb"}{$Memb_Pos}{"type"};
- detect_TypeUsing($Tid_TDid{$LibVersion}{$Member_TypeId}, $Member_TypeId, $LibVersion);
- }
- if($Type{"Type"} eq "FuncPtr")
- {
- my $ReturnType = $Type{"Return"};
- detect_TypeUsing($Tid_TDid{$LibVersion}{$ReturnType}, $ReturnType, $LibVersion);
- }
- }
- elsif($Type{"Type"} =~ /Const|Pointer|Ref|Volatile|Restrict|Array|/)
- {
- $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
- detect_TypeUsing($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
- }
- elsif($Type{"Type"} eq "Intrinsic")
- {
- $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
- }
- else
- {
- delete($TypeDescr{$LibVersion}{$TypeDeclId}{$TypeId});
- if(not keys(%{$TypeDescr{$LibVersion}{$TypeDeclId}}))
- {
- delete($TypeDescr{$LibVersion}{$TypeDeclId});
- }
- delete($Tid_TDid{$LibVersion}{$TypeId}) if($Tid_TDid{$LibVersion}{$TypeId} eq $TypeDeclId);
- }
-}
-
-sub initializeClassVirtFunc($)
-{
- my $LibVersion = $_[0];
- foreach my $Interface (keys(%{$CompleteSignature{$LibVersion}}))
- {
- if($CompleteSignature{$LibVersion}{$Interface}{"Virt"})
- {
- my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{"Name"};
- $ClassVirtFunc{$LibVersion}{$ClassName}{$Interface} = 1;
- $ClassIdVirtFunc{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{$Interface} = 1;
- $ClassId{$LibVersion}{$ClassName} = $CompleteSignature{$LibVersion}{$Interface}{"Class"};
- }
- }
-}
-
-sub checkVirtFuncRedefinitions($)
-{
- my $LibVersion = $_[0];
- foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
- {
- $CheckedTypes{$Class_Name} = 1;
- foreach my $VirtFuncName (keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
- {
- $CompleteSignature{$LibVersion}{$VirtFuncName}{"VirtualRedefine"} = find_virtual_method_in_base_classes($VirtFuncName, $ClassId{$LibVersion}{$Class_Name}, $LibVersion);
- }
- }
-}
-
-sub setVirtFuncPositions($)
-{
- my $LibVersion = $_[0];
- foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
- {
- $CheckedTypes{$Class_Name} = 1;
- my $Position = 0;
- foreach my $VirtFuncName (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
- {
- if($ClassVirtFunc{1}{$Class_Name}{$VirtFuncName} and $ClassVirtFunc{2}{$Class_Name}{$VirtFuncName} and not $CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"} and not $CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
- {
- $CompleteSignature{$LibVersion}{$VirtFuncName}{"Position"} = $Position;
- $Position += 1;
- }
- }
- }
-}
-
-sub check_VirtualTable($$)
-{
- my ($TargetFunction, $LibVersion) = @_;
- my $Class_Id = $CompleteSignature{$LibVersion}{$TargetFunction}{"Class"};
- my $Class_DId = $Tid_TDid{$LibVersion}{$Class_Id};
- my %Class_Type = get_Type($Class_DId, $Class_Id, $LibVersion);
- $CheckedTypes{$Class_Type{"Name"}} = 1;
- foreach my $VirtFuncName (keys(%{$ClassVirtFunc{2}{$Class_Type{"Name"}}}))
- {#Added
- if($ClassId{1}{$Class_Type{"Name"}} and not $ClassVirtFunc{1}{$Class_Type{"Name"}}{$VirtFuncName} and $AddedInt{$VirtFuncName})
- {
- if($CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
- {
- if($TargetFunction eq $VirtFuncName)
- {
- my $BaseClass_Id = $CompleteSignature{2}{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
- my %BaseClass_Type = get_Type($Tid_TDid{2}{$BaseClass_Id}, $BaseClass_Id, 2);
- my $BaseClass_Name = $BaseClass_Type{"Name"};
- %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition"}{$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}}}=(
- "Type_Name"=>$Class_Type{"Name"},
- "Type_Type"=>$Class_Type{"Type"},
- "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
- "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
- "Target"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
- "Signature"=>$tr_name{$TargetFunction},
- "Old_Value"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
- "New_Value"=>$tr_name{$TargetFunction},
- "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
- "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
- }
- }
- elsif($TargetFunction ne $VirtFuncName)
- {
- %{$CompatProblems{$TargetFunction}{"Added_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
- "Type_Name"=>$Class_Type{"Name"},
- "Type_Type"=>$Class_Type{"Type"},
- "Header"=>$Class_Type{"Header"},
- "Line"=>$Class_Type{"Line"},
- "Target"=>$tr_name{$VirtFuncName},
- "Signature"=>$tr_name{$TargetFunction},
- "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
- "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
- }
- }
- }
- foreach my $VirtFuncName (keys(%{$ClassVirtFunc{1}{$Class_Type{"Name"}}}))
- {#Withdrawn
- if($ClassId{2}{$Class_Type{"Name"}} and not $ClassVirtFunc{2}{$Class_Type{"Name"}}{$VirtFuncName} and $WithdrawnInt{$VirtFuncName})
- {
- if($CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"})
- {
- if($TargetFunction eq $VirtFuncName)
- {
- my $BaseClass_Id = $CompleteSignature{1}{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
- my $BaseClass_Name = $TypeDescr{1}{$Tid_TDid{1}{$BaseClass_Id}}{$BaseClass_Id}{"Name"};
- %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition_B"}{$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}}}=(
- "Type_Name"=>$Class_Type{"Name"},
- "Type_Type"=>$Class_Type{"Type"},
- "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
- "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
- "Target"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
- "Signature"=>$tr_name{$TargetFunction},
- "Old_Value"=>$tr_name{$TargetFunction},
- "New_Value"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
- "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
- "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
- }
- }
- else
- {
- %{$CompatProblems{$TargetFunction}{"Withdrawn_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
- "Type_Name"=>$Class_Type{"Name"},
- "Type_Type"=>$Class_Type{"Type"},
- "Header"=>$Class_Type{"Header"},
- "Line"=>$Class_Type{"Line"},
- "Target"=>$tr_name{$VirtFuncName},
- "Signature"=>$tr_name{$TargetFunction},
- "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
- "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
- }
- }
- }
-}
-
-sub find_virtual_method_in_base_classes($$$)
-{
- my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
- foreach my $BaseClass_Id (keys(%{$TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$Checked_ClassId}}{$Checked_ClassId}{"BaseClass"}}))
- {
- my $VirtMethodInClass = find_virtual_method_in_class($VirtFuncName, $BaseClass_Id, $LibVersion);
- if($VirtMethodInClass)
- {
- return $VirtMethodInClass;
- }
- my $VirtMethodInBaseClasses = find_virtual_method_in_base_classes($VirtFuncName, $BaseClass_Id, $LibVersion);
- if($VirtMethodInBaseClasses)
- {
- return $VirtMethodInBaseClasses;
- }
- }
- return "";
-}
-
-sub find_virtual_method_in_class($$$)
-{
- my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
- my $Suffix = getFuncSuffix($VirtFuncName, $LibVersion);
- foreach my $Checked_VirtFuncName (keys(%{$ClassIdVirtFunc{$LibVersion}{$Checked_ClassId}}))
- {
- if($Suffix eq getFuncSuffix($Checked_VirtFuncName, $LibVersion)
- 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"})))
- {
- return $Checked_VirtFuncName;
- }
- }
- return "";
-}
-
-sub getFuncSuffix($$)
-{
- my ($FuncName, $LibVersion) = @_;
- my $ClassId = $CompleteSignature{$LibVersion}{$FuncName}{"Class"};
- my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ClassId}}{$ClassId}{"Name"};
- my $ShortName = $CompleteSignature{$LibVersion}{$FuncName}{"ShortName"};
- my $Suffix = $tr_name{$FuncName};
- $Suffix =~ s/\A$ClassName\:\:[~]*$ShortName[ ]*//g;
- return $Suffix;
-}
-
-sub isRecurType($$$$)
-{
- foreach (@RecurTypes)
- {
- if($_->{"Tid1"} eq $_[0]
- and $_->{"TDid1"} eq $_[1]
- and $_->{"Tid2"} eq $_[2]
- and $_->{"TDid2"} eq $_[3])
- {
- return 1;
- }
- }
- return 0;
-}
-
-sub find_MemberPair_Pos_byName($$)
-{
- my ($Member_Name, $Pair_Type) = @_;
- foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
- {
- if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"name"} eq $Member_Name)
- {
- return $MemberPair_Pos;
- }
- }
- return "lost";
-}
-
-sub getBitfieldSum($$)
-{
- my ($Member_Pos, $Pair_Type) = @_;
- my $BitfieldSum = 0;
- while($Member_Pos>-1)
- {
- return $BitfieldSum if(not $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"});
- $BitfieldSum += $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"};
- $Member_Pos -= 1;
- }
- return $BitfieldSum;
-}
-
-sub find_MemberPair_Pos_byVal($$)
-{
- my ($Member_Value, $Pair_Type) = @_;
- foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
- {
- if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"value"} eq $Member_Value)
- {
- return $MemberPair_Pos;
- }
- }
- return "lost";
-}
-
-my %Priority_Value=(
-"High"=>3,
-"Medium"=>2,
-"Low"=>1
-);
-
-sub max_priority($$)
-{
- my ($Priority1, $Priority2) = @_;
- if(cmp_priority($Priority1, $Priority2))
- {
- return $Priority1;
- }
- else
- {
- return $Priority2;
- }
-}
-
-sub cmp_priority($$)
-{
- my ($Priority1, $Priority2) = @_;
- return ($Priority_Value{$Priority1}>$Priority_Value{$Priority2});
-}
-
-sub set_Problems_Priority()
-{
- foreach my $InterfaceName (sort keys(%CompatProblems))
- {
- foreach my $Kind (sort keys(%{$CompatProblems{$InterfaceName}}))
- {
- foreach my $Location (sort keys(%{$CompatProblems{$InterfaceName}{$Kind}}))
- {
- my $IsInTypeInternals = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"IsInTypeInternals"};
- my $InitialType_Type = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"InitialType_Type"};
- if($Kind eq "Function_Become_Static")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Function_Become_NonStatic")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Parameter_Type_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Parameter_Type")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Withdrawn_Parameter")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Added_Parameter")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Parameter_BaseType_And_Size")
- {
- if($InitialType_Type eq "Pointer")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- }
- elsif($Kind eq "Parameter_BaseType")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Parameter_PointerLevel")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Return_Type_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Return_Type")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Return_BaseType_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Return_BaseType")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Return_PointerLevel")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- if($Kind eq "Added_Virtual_Function")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Withdrawn_Virtual_Function")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Virtual_Function_Position")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- elsif($Kind eq "Virtual_Function_Redefinition")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Virtual_Function_Redefinition_B")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Size")
- {
- if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- if($IsInTypeInternals)
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- }
- }
- elsif($Kind eq "BaseType")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Added_Member_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Added_Middle_Member_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Withdrawn_Member_And_Size")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Withdrawn_Member")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
- {
- if($IsInTypeInternals)
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- }
- elsif($Kind eq "Withdrawn_Middle_Member")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Member_Rename")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Enum_Member_Value")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- elsif($Kind eq "Enum_Member_Name")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Member_Type_And_Size")
- {
- if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- if($IsInTypeInternals)
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- }
- }
- elsif($Kind eq "Member_Type")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Member_BaseType_And_Size")
- {
- if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- if($IsInTypeInternals)
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
- }
- }
- }
- elsif($Kind eq "Member_BaseType")
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- elsif($Kind eq "Member_PointerLevel")
- {
- if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- if($IsInTypeInternals)
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
- }
- else
- {
- $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
- }
- }
- }
- }
- }
- }
-}
-
-sub pushType($$$$)
-{
- my %TypeDescriptor=(
- "Tid1" => $_[0],
- "TDid1" => $_[1],
- "Tid2" => $_[2],
- "TDid2" => $_[3] );
- push(@RecurTypes, \%TypeDescriptor);
-}
-
-sub mergeTypes($$$$)
-{
- my ($Type1_Id, $Type1_DId, $Type2_Id, $Type2_DId) = @_;
- my (%Sub_SubProblems, %SubProblems) = ();
- if((not $Type1_Id and not $Type1_DId) or (not $Type2_Id and not $Type2_DId))
- {#Not Empty Inputs Only
- return ();
- }
- if($Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId})
- {#Already Merged
- return %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}};
- }
- my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
- my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
- my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
- my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
- return () if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"});
- if(isRecurType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"}))
- {#Recursive Declarations
- return ();
- }
- return if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
- return if($OpaqueTypes{1}{$Type1_Pure{"Name"}} or $OpaqueTypes{2}{$Type1_Pure{"Name"}} or $OpaqueTypes{1}{$Type1{"Name"}} or $OpaqueTypes{2}{$Type1{"Name"}});
-
- my %Typedef_1 = goToFirst($Type1{"TDid"}, $Type1{"Tid"}, 1, "Typedef");
- my %Typedef_2 = goToFirst($Type2{"TDid"}, $Type2{"Tid"}, 2, "Typedef");
- if($Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef" and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
- {
- my %Base_1 = get_OneStep_BaseType($Typedef_1{"TDid"}, $Typedef_1{"Tid"}, 1);
- my %Base_2 = get_OneStep_BaseType($Typedef_2{"TDid"}, $Typedef_2{"Tid"}, 2);
- if($Base_1{"Name"}!~/anon\-/ and $Base_2{"Name"}!~/anon\-/
- and ($Base_1{"Name"} ne $Base_2{"Name"}))
- {
- %{$SubProblems{"BaseType"}{$Typedef_1{"Name"}}}=(
- "Type_Name"=>$Typedef_1{"Name"},
- "Type_Type"=>"Typedef",
- "Header"=>$Typedef_2{"Header"},
- "Line"=>$Typedef_2{"Line"},
- "Old_Value"=>$Base_1{"Name"},
- "New_Value"=>$Base_2{"Name"} );
- }
- }
-
- if(($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} ne "Pointer") and $Type1_Pure{"Name"}!~/anon\-/)
- {#Different types
- return ();
- }
-
- pushType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"});
- if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} =~ /Struct|Class|Union/))
- {#Check Size
- if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
- {
- %{$SubProblems{"Size"}{$Type1_Pure{"Name"}}}=(
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Value"=>$Type1_Pure{"Size"},
- "New_Value"=>$Type2_Pure{"Size"} );
- }
- }
- 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[ ]*\*/))
- {#Check "void *"
- pop(@RecurTypes);
- return ();
- }
- if($Type1_Pure{"BaseType"}{"Tid"} and $Type2_Pure{"BaseType"}{"Tid"})
- {#Check Base Types
- %Sub_SubProblems = &mergeTypes($Type1_Pure{"BaseType"}{"Tid"}, $Type1_Pure{"BaseType"}{"TDid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"TDid"});
- foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
- {
- foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
- {
- %{$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}} = %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
- $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
- }
- }
- }
- foreach my $Member_Pos (sort keys(%{$Type1_Pure{"Memb"}}))
- {#Check Members
- next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
- my $Member_Name = $Type1_Pure{"Memb"}{$Member_Pos}{"name"};
- next if(not $Member_Name);
- my $Member_Location = $Member_Name;
- my $MemberPair_Pos = find_MemberPair_Pos_byName($Member_Name, \%Type2_Pure);
- if(($MemberPair_Pos eq "lost") and (($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class")))
- {#Withdrawn_Member
- if($Member_Pos > keys(%{$Type2_Pure{"Memb"}}) - 1)
- {
- if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
- {
- %{$SubProblems{"Withdrawn_Member_And_Size"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Size"=>$Type1_Pure{"Size"},
- "New_Size"=>$Type2_Pure{"Size"} );
- }
- else
- {
- %{$SubProblems{"Withdrawn_Member"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"} );
- }
- next;
- }
- elsif($Member_Pos < keys(%{$Type1_Pure{"Memb"}}) - 1)
- {
- my $MemberType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
- my %MemberType_Pure = get_PureType($Tid_TDid{1}{$MemberType_Id}, $MemberType_Id, 1);
- my $MemberStraightPairType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
- my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{2}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 2);
-
- if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure) eq "lost")
- {
- %{$SubProblems{"Member_Rename"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
- "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
- $MemberPair_Pos = $Member_Pos;
- }
- else
- {
- if($Type1_Pure{"Memb"}{$Member_Pos}{"bitfield"})
- {
- my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type1_Pure)%($POINTER_SIZE*8);
- if($BitfieldSum and $BitfieldSum-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"}>=0)
- {
- %{$SubProblems{"Withdrawn_Middle_Member"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"} );
- next;
- }
- }
- %{$SubProblems{"Withdrawn_Middle_Member_And_Size"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"} );
- next;
- }
- }
- }
- if($Type1_Pure{"Type"} eq "Enum")
- {
- my $Member_Value1 = $Type1_Pure{"Memb"}{$Member_Pos}{"value"};
- next if(not $Member_Value1);
- my $Member_Value2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"};
- if($MemberPair_Pos eq "lost")
- {
- $MemberPair_Pos = find_MemberPair_Pos_byVal($Member_Value1, \%Type2_Pure);
- if($MemberPair_Pos ne "lost")
- {
- %{$SubProblems{"Enum_Member_Name"}{$Type1_Pure{"Memb"}{$Member_Pos}{"value"}}}=(
- "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>"Enum",
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
- "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"name"} );
- }
- }
- else
- {
- if($Member_Value1 ne "" and $Member_Value2 ne "")
- {
- if($Member_Value1 ne $Member_Value2)
- {
- %{$SubProblems{"Enum_Member_Value"}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>"Enum",
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
- "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"} );
- }
- }
- }
- next;
- }
- my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
- my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
- %Sub_SubProblems = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Member");
- foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
- {
- %{$SubProblems{$Sub_SubProblemType}{$Member_Name}}=(
- "Target"=>$Member_Name,
- "Member_Position"=>$Member_Pos,
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"});
- @{$SubProblems{$Sub_SubProblemType}{$Member_Name}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}};
- }
- if($MemberType1_Id and $MemberType2_Id)
- {#checking member type change (replace)
- %Sub_SubProblems = &mergeTypes($MemberType1_Id, $Tid_TDid{1}{$MemberType1_Id}, $MemberType2_Id, $Tid_TDid{2}{$MemberType2_Id});
- foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
- {
- foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
- {
- my $NewLocation = ($Sub_SubLocation)?$Member_Location."->".$Sub_SubLocation:$Member_Location;
- %{$SubProblems{$Sub_SubProblemType}{$NewLocation}}=(
- "IsInTypeInternals"=>"Yes");
- @{$SubProblems{$Sub_SubProblemType}{$NewLocation}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
- if($Sub_SubLocation !~ /\-\>/)
- {
- $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Member_Type_Name"} = get_TypeName($MemberType1_Id, 1);
- $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($MemberType1_Id, 1);
- }
- }
- }
- }
- }
- if(($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class"))
- {
- foreach my $Member_Pos (sort keys(%{$Type2_Pure{"Memb"}}))
- {#checking added members
- next if(not $Type2_Pure{"Memb"}{$Member_Pos}{"name"});
- my $MemberPair_Pos = find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure);
- if($MemberPair_Pos eq "lost")
- {#Added_Member
- if($Member_Pos > keys(%{$Type1_Pure{"Memb"}}) - 1)
- {
- if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
- {
- if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
- {
- my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
- next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
- }
- %{$SubProblems{"Added_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
- "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"} );
- }
- }
- else
- {
- my $MemberType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
- my $MemberType_DId = $Tid_TDid{2}{$MemberType_Id};
- my %MemberType_Pure = get_PureType($MemberType_DId, $MemberType_Id, 2);
-
- my $MemberStraightPairType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
- my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{1}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 1);
-
- if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type1_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type2_Pure) eq "lost")
- {
- next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
- %{$SubProblems{"Member_Rename"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
- "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"},
- "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
- "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
- }
- else
- {
- if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
- {
- if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
- {
- my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
- next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
- }
- %{$SubProblems{"Added_Middle_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
- "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
- "Type_Name"=>$Type1_Pure{"Name"},
- "Type_Type"=>$Type1_Pure{"Type"},
- "Header"=>$Type2_Pure{"Header"},
- "Line"=>$Type2_Pure{"Line"} );
- }
- }
- }
- }
- }
- }
- %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}} = %SubProblems;
- pop(@RecurTypes);
- return %SubProblems;
-}
-
-sub get_TypeName($$)
-{
- my ($TypeId, $LibVersion) = @_;
- return $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$TypeId}}{$TypeId}{"Name"};
-}
-
-sub goToFirst($$$$)
-{
- my ($TypeDId, $TypeId, $LibVersion, $Type_Type) = @_;
- if(defined $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type})
- {
- return %{$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type}};
- }
- return () if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
- return () if(not $Type{"Type"});
- if($Type{"Type"} ne $Type_Type)
- {
- return () if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
- %Type = goToFirst($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
- }
- $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type} = \%Type;
- return %Type;
-}
-
-my %TypeSpecAttributes = (
- "Ref" => 1,
- "Const" => 1,
- "Volatile" => 1,
- "Restrict" => 1,
- "Typedef" => 1
-);
-
-sub get_PureType($$$)
-{
- my ($TypeDId, $TypeId, $LibVersion) = @_;
- return "" if(not $TypeId);
- if(defined $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion})
- {
- return %{$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion}};
- }
- return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
- if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
- {
- $CheckedTypes{$Type{"Name"}} = 1;
- }
- return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
- if($TypeSpecAttributes{$Type{"Type"}})
- {
- %Type = get_PureType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
- }
- $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
- return %Type;
-}
-
-sub get_PointerLevel($$$)
-{
- my ($TypeDId, $TypeId, $LibVersion) = @_;
- return "" if(not $TypeId);
- if(defined $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion})
- {
- return $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion};
- }
- return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
- return 0 if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
- my $PointerLevel = 0;
- if($Type{"Type"} eq "Pointer")
- {
- $PointerLevel += 1;
- }
- $PointerLevel += get_PointerLevel($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
- $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion} = $PointerLevel;
- return $PointerLevel;
-}
-
-sub get_BaseType($$$)
-{
- my ($TypeDId, $TypeId, $LibVersion) = @_;
- return "" if(not $TypeId);
- if(defined $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion})
- {
- return %{$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion}};
- }
- return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
- if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
- {
- $CheckedTypes{$Type{"Name"}} = 1;
- }
- return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
- %Type = get_BaseType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
- $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
- return %Type;
-}
-
-sub get_OneStep_BaseType($$$)
-{
- my ($TypeDId, $TypeId, $LibVersion) = @_;
- return "" if(not $TypeId);
- return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
- return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
- return get_Type($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
-}
-
-sub get_Type($$$)
-{
- my ($TypeDId, $TypeId, $LibVersion) = @_;
- return "" if(not $TypeId);
- return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
- return %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
-}
-
-sub mergeLibs()
-{
- foreach my $Interface (sort keys(%AddedInt))
- {#checking added interfaces
- next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
- next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
- next if(defined $AppPath and not $InterfacesList_App{$Interface});
- next if($FuncAttr{2}{$Interface}{"Private"});
- next if(not $FuncAttr{2}{$Interface}{"Header"});
- %{$CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}}=(
- "Header"=>$FuncAttr{2}{$Interface}{"Header"},
- "Line"=>$FuncAttr{2}{$Interface}{"Line"},
- "Signature"=>$FuncAttr{2}{$Interface}{"Signature"},
- "New_SoName"=>$Interface_Library{2}{$Interface} );
- }
- foreach my $Interface (sort keys(%WithdrawnInt))
- {#checking withdrawn interfaces
- next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
- next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
- next if(defined $AppPath and not $InterfacesList_App{$Interface});
- next if($FuncAttr{1}{$Interface}{"Private"});
- next if(not $FuncAttr{1}{$Interface}{"Header"});
- %{$CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}}=(
- "Header"=>$FuncAttr{1}{$Interface}{"Header"},
- "Line"=>$FuncAttr{1}{$Interface}{"Line"},
- "Signature"=>$FuncAttr{1}{$Interface}{"Signature"},
- "Old_SoName"=>$Interface_Library{1}{$Interface} );
- }
-}
-
-sub mergeSignatures()
-{
- my %SubProblems = ();
-
- prepareInterfaces(1);
- prepareInterfaces(2);
- %FuncDescr=();
-
- initializeClassVirtFunc(1);
- initializeClassVirtFunc(2);
-
- checkVirtFuncRedefinitions(1);
- checkVirtFuncRedefinitions(2);
-
- setVirtFuncPositions(1);
- setVirtFuncPositions(2);
-
- foreach my $Interface (sort keys(%AddedInt))
- {#collecting the attributes of added interfaces
- next if($CheckedInterfaces{$Interface});
- if($CompleteSignature{2}{$Interface})
- {
- if($CompleteSignature{2}{$Interface}{"Private"})
- {
- $FuncAttr{2}{$Interface}{"Private"} = 1;
- }
- if($CompleteSignature{2}{$Interface}{"Protected"})
- {
- $FuncAttr{2}{$Interface}{"Protected"} = 1;
- }
- if($CompleteSignature{2}{$Interface}{"Header"})
- {
- $FuncAttr{2}{$Interface}{"Header"} = $CompleteSignature{2}{$Interface}{"Header"};
- }
- if($CompleteSignature{2}{$Interface}{"Line"})
- {
- $FuncAttr{2}{$Interface}{"Line"} = $CompleteSignature{2}{$Interface}{"Line"};
- }
- $FuncAttr{2}{$Interface}{"Signature"} = get_Signature($Interface, 2);
- foreach my $ParamPos (keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
- {
- my $ParamType_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
- my $ParamType_DId = $Tid_TDid{2}{$ParamType_Id};
- my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 2);
- }
- #checking virtual table
- check_VirtualTable($Interface, 2);
- $CheckedInterfaces{$Interface} = 1;
- }
- }
- foreach my $Interface (sort keys(%WithdrawnInt))
- {#collecting the attributes of withdrawn interfaces
- next if($CheckedInterfaces{$Interface});
- if($CompleteSignature{1}{$Interface})
- {
- if($CompleteSignature{1}{$Interface}{"Private"})
- {
- $FuncAttr{1}{$Interface}{"Private"} = 1;
- }
- if($CompleteSignature{1}{$Interface}{"Protected"})
- {
- $FuncAttr{1}{$Interface}{"Protected"} = 1;
- }
- if($CompleteSignature{1}{$Interface}{"Header"})
- {
- $FuncAttr{1}{$Interface}{"Header"} = $CompleteSignature{1}{$Interface}{"Header"};
- }
- if($CompleteSignature{1}{$Interface}{"Line"})
- {
- $FuncAttr{1}{$Interface}{"Line"} = $CompleteSignature{1}{$Interface}{"Line"};
- }
- $FuncAttr{1}{$Interface}{"Signature"} = get_Signature($Interface, 1);
- foreach my $ParamPos (keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
- {
- my $ParamType_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
- my $ParamType_DId = $Tid_TDid{1}{$ParamType_Id};
- my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 1);
- }
- #checking virtual table
- check_VirtualTable($Interface, 1);
- $CheckedInterfaces{$Interface} = 1;
- }
- }
-
- foreach my $Interface (sort keys(%{$CompleteSignature{1}}))
- {#checking interfaces
- if(($Interface !~ /\@/) and ($SymVer{1}{$Interface} =~ /\A(.*)[\@]+/))
- {
- next if($1 eq $Interface);
- }
- my ($MnglName, $SymbolVersion) = ($Interface, "");
- if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
- {
- ($MnglName, $SymbolVersion) = ($1, $2);
- }
- next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
- next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
- next if(defined $AppPath and not $InterfacesList_App{$Interface});
- next if($CheckedInterfaces{$Interface});
- next if($CompleteSignature{1}{$Interface}{"Private"});
- next if(not $CompleteSignature{1}{$Interface}{"Header"} or not $CompleteSignature{2}{$Interface}{"Header"});
- next if(not $CompleteSignature{1}{$Interface}{"MnglName"} or not $CompleteSignature{2}{$Interface}{"MnglName"});
- next if((not $CompleteSignature{1}{$Interface}{"PureVirt"} and $CompleteSignature{2}{$Interface}{"PureVirt"}) or ($CompleteSignature{1}{$Interface}{"PureVirt"} and not $CompleteSignature{2}{$Interface}{"PureVirt"}));
- $CheckedInterfaces{$Interface} = 1;
- #checking virtual table
- check_VirtualTable($Interface, 1);
- #checking attributes
- if($CompleteSignature{2}{$Interface}{"Static"} and not $CompleteSignature{1}{$Interface}{"Static"})
- {
- %{$CompatProblems{$Interface}{"Function_Become_Static"}{"Attributes"}}=(
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Signature"=>get_Signature($Interface, 1),
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface} );
- }
- elsif(not $CompleteSignature{2}{$Interface}{"Static"} and $CompleteSignature{1}{$Interface}{"Static"})
- {
- %{$CompatProblems{$Interface}{"Function_Become_NonStatic"}{"Attributes"}}=(
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Signature"=>get_Signature($Interface, 1),
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface} );
- }
- if($CompleteSignature{1}{$Interface}{"Virt"} and $CompleteSignature{2}{$Interface}{"Virt"})
- {
- if($CompleteSignature{1}{$Interface}{"Position"}!=$CompleteSignature{2}{$Interface}{"Position"})
- {
- my $Class_Id = $CompleteSignature{1}{$Interface}{"Class"};
- my $Class_DId = $Tid_TDid{1}{$Class_Id};
- my %Class_Type = get_Type($Class_DId, $Class_Id, 1);
- %{$CompatProblems{$Interface}{"Virtual_Function_Position"}{$tr_name{$MnglName}}}=(
- "Type_Name"=>$Class_Type{"Name"},
- "Type_Type"=>$Class_Type{"Type"},
- "Header"=>$Class_Type{"Header"},
- "Line"=>$Class_Type{"Line"},
- "Old_Value"=>$CompleteSignature{1}{$Interface}{"Position"},
- "New_Value"=>$CompleteSignature{2}{$Interface}{"Position"},
- "Signature"=>get_Signature($Interface, 1),
- "Target"=>$tr_name{$MnglName},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface} );
- }
- }
- foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
- {#checking added parameters
- last if($Interface=~/\A_Z/);
- if(not defined $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos})
- {#checking withdrawn parameters
- my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
- my $Parameter_Name = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"name"};
- last if(get_TypeName($ParamType2_Id, 2) eq "...");
- %{$CompatProblems{$Interface}{"Added_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
- "Target"=>$Parameter_Name,
- "Parameter_Position"=>$ParamPos,
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface});
- }
- }
- foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
- {#checking parameters
- my $ParamType1_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
- my $Parameter_Name = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"name"};
- if(not defined $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos} and get_TypeName($ParamType1_Id, 1) ne "..." and $Interface!~/\A_Z/)
- {#checking withdrawn parameters
- %{$CompatProblems{$Interface}{"Withdrawn_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
- "Target"=>$Parameter_Name,
- "Parameter_Position"=>$ParamPos,
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface});
- next;
- }
- my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
- next if(not $ParamType1_Id or not $ParamType2_Id);
- my $Parameter_Location = ($Parameter_Name)?$Parameter_Name:num_to_str($ParamPos+1)." Parameter";
-
- #checking type change(replace)
- %SubProblems = detectTypeChange($ParamType1_Id, $ParamType2_Id, "Parameter");
- foreach my $SubProblemType (keys(%SubProblems))
- {
- %{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}=(
- "Target"=>$Parameter_Name,
- "Parameter_Position"=>$ParamPos,
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface});
- @{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
- }
- @RecurTypes = ();
- #checking type definition changes
- %SubProblems = mergeTypes($ParamType1_Id, $Tid_TDid{1}{$ParamType1_Id}, $ParamType2_Id, $Tid_TDid{2}{$ParamType2_Id});
- foreach my $SubProblemType (keys(%SubProblems))
- {
- foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
- {
- my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
- %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface},
- "Parameter_Type_Name"=>get_TypeName($ParamType1_Id, 1),
- "Parameter_Position"=>$ParamPos,
- "Parameter_Name"=>$Parameter_Name);
- @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
- if($SubLocation !~ /\-\>/)
- {
- $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ParamType1_Id, 1);
- }
- }
- }
- }
- #checking return type
- my $ReturnType1_Id = $CompleteSignature{1}{$Interface}{"Return"};
- my $ReturnType2_Id = $CompleteSignature{2}{$Interface}{"Return"};
- %SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return");
- foreach my $SubProblemType (keys(%SubProblems))
- {
- %{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}=(
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface});
- @{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
- }
- if($ReturnType1_Id and $ReturnType2_Id)
- {
- @RecurTypes = ();
- %SubProblems = mergeTypes($ReturnType1_Id, $Tid_TDid{1}{$ReturnType1_Id}, $ReturnType2_Id, $Tid_TDid{2}{$ReturnType2_Id});
- foreach my $SubProblemType (keys(%SubProblems))
- {
- foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
- {
- my $NewLocation = ($SubLocation)?"RetVal->".$SubLocation:"RetVal";
- %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface},
- "Return_Type_Name"=>get_TypeName($ReturnType1_Id, 1) );
- @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
- if($SubLocation !~ /\-\>/)
- {
- $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ReturnType1_Id, 1);
- }
- }
- }
- }
-
- #checking object type
- my $ObjectType1_Id = $CompleteSignature{1}{$Interface}{"Class"};
- my $ObjectType2_Id = $CompleteSignature{2}{$Interface}{"Class"};
- if($ObjectType1_Id and $ObjectType2_Id)
- {
- my $ThisType1_Id = getTypeIdByName(get_TypeName($ObjectType1_Id, 1)."*const", 1);
- my $ThisType2_Id = getTypeIdByName(get_TypeName($ObjectType2_Id, 2)."*const", 2);
- if($ThisType1_Id and $ThisType2_Id)
- {
- @RecurTypes = ();
- %SubProblems = mergeTypes($ThisType1_Id, $Tid_TDid{1}{$ThisType1_Id}, $ThisType2_Id, $Tid_TDid{2}{$ThisType2_Id});
- foreach my $SubProblemType (keys(%SubProblems))
- {
- foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
- {
- my $NewLocation = ($SubLocation)?"Obj->".$SubLocation:"Obj";
- %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
- "Signature"=>get_Signature($Interface, 1),
- "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
- "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
- "Old_SoName"=>$Interface_Library{1}{$Interface},
- "New_SoName"=>$Interface_Library{2}{$Interface},
- "Object_Type_Name"=>get_TypeName($ObjectType1_Id, 1) );
- @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
- if($SubLocation !~ /\-\>/)
- {
- $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ObjectType1_Id, 1);
- }
- }
- }
- }
- }
- }
- set_Problems_Priority();
-}
-
-sub getTypeIdByName($$)
-{
- my ($TypeName, $Version) = @_;
- return $TName_Tid{$Version}{correctName($TypeName)};
-}
-
-sub detectTypeChange($$$)
-{
- my ($Type1_Id, $Type2_Id, $Prefix) = @_;
- my %LocalProblems = ();
- my $Type1_DId = $Tid_TDid{1}{$Type1_Id};
- my $Type2_DId = $Tid_TDid{2}{$Type2_Id};
- my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
- my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
- my %Type1_Base = get_BaseType($Type1_DId, $Type1_Id, 1);
- my %Type2_Base = get_BaseType($Type2_DId, $Type2_Id, 2);
- my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
- my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
- my $Type1_PointerLevel = get_PointerLevel($Type1_DId, $Type1_Id, 1);
- my $Type2_PointerLevel = get_PointerLevel($Type2_DId, $Type2_Id, 2);
- 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 "");
- if($Type1_Base{"Name"} ne $Type2_Base{"Name"})
- {#base type change
- if($Type1_Base{"Name"}!~/anon\-/ and $Type2_Base{"Name"}!~/anon\-/)
- {
- if($Type1_Base{"Size"}!=$Type2_Base{"Size"})
- {
- %{$LocalProblems{$Prefix."_BaseType_And_Size"}}=(
- "Old_Value"=>$Type1_Base{"Name"},
- "New_Value"=>$Type2_Base{"Name"},
- "Old_Size"=>$Type1_Base{"Size"},
- "New_Size"=>$Type2_Base{"Size"},
- "InitialType_Type"=>$Type1_Pure{"Type"});
- }
- else
- {
- %{$LocalProblems{$Prefix."_BaseType"}}=(
- "Old_Value"=>$Type1_Base{"Name"},
- "New_Value"=>$Type2_Base{"Name"},
- "InitialType_Type"=>$Type1_Pure{"Type"});
- }
- }
- }
- elsif($Type1{"Name"} ne $Type2{"Name"})
- {#type change
- if($Type1{"Name"}!~/anon\-/ and $Type2{"Name"}!~/anon\-/)
- {
- if($Type1{"Size"}!=$Type2{"Size"})
- {
- %{$LocalProblems{$Prefix."_Type_And_Size"}}=(
- "Old_Value"=>$Type1{"Name"},
- "New_Value"=>$Type2{"Name"},
- "Old_Size"=>($Type1{"Type"} eq "Array")?$Type1{"Size"}*$Type1_Base{"Size"}:$Type1{"Size"},
- "New_Size"=>($Type2{"Type"} eq "Array")?$Type2{"Size"}*$Type2_Base{"Size"}:$Type2{"Size"},
- "InitialType_Type"=>$Type1_Pure{"Type"});
- }
- else
- {
- %{$LocalProblems{$Prefix."_Type"}}=(
- "Old_Value"=>$Type1{"Name"},
- "New_Value"=>$Type2{"Name"},
- "InitialType_Type"=>$Type1_Pure{"Type"});
- }
- }
- }
-
- if($Type1_PointerLevel!=$Type2_PointerLevel)
- {
- %{$LocalProblems{$Prefix."_PointerLevel"}}=(
- "Old_Value"=>$Type1_PointerLevel,
- "New_Value"=>$Type2_PointerLevel);
- }
- return %LocalProblems;
-}
-
-sub htmlSpecChars($)
-{
- my $Str = $_[0];
- $Str =~ s/\&([^#])/&amp;$1/g;
- $Str =~ s/</&lt;/g;
- $Str =~ s/>/&gt;/g;
- $Str =~ s/([^ ])( )([^ ])/$1\@ALONE_SP\@$3/g;
- $Str =~ s/ /&nbsp;/g;
- $Str =~ s/\@ALONE_SP\@/ /g;
- $Str =~ s/\n/<br\/>/g;
- return $Str;
-}
-
-sub highLight_Signature($)
-{
- my $Signature = $_[0];
- return highLight_Signature_PPos_Italic($Signature, "", 0, 0);
-}
-
-sub highLight_Signature_Italic($)
-{
- my $Signature = $_[0];
- return highLight_Signature_PPos_Italic($Signature, "", 1, 0);
-}
-
-sub highLight_Signature_Italic_Color($)
-{
- my $Signature = $_[0];
- return highLight_Signature_PPos_Italic($Signature, "", 1, 1);
-}
-
-sub highLight_Signature_PPos_Italic($$$$)
-{
- my ($FullSignature, $Parameter_Position, $ItalicParams, $ColorParams) = @_;
- my ($Signature, $SymbolVersion) = ($FullSignature, "");
- if($FullSignature =~ /\A(.+)[\@]+(.+)\Z/)
- {
- ($Signature, $SymbolVersion) = ($1, $2);
- }
- if($Signature=~/\Atypeinfo\W/)
- {
- return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
- }
- if($Signature!~/\)(| const)\Z/)
- {
- return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
- }
- $Signature =~ /(.+?)\(.*\)(| const)\Z/;
- my ($Begin, $End) = ($1, $2);
- my @Parts = ();
- my $Part_Num = 0;
- foreach my $Part (get_Signature_Parts($Signature, 1))
- {
- $Part =~ s/\A\s+|\s+\Z//g;
- my ($Part_Styled, $ParamName) = ($Part, "");
- if($Part=~/\([\*]+(\w+)\)/i)
- {#func-ptr
- $ParamName = $1;
- }
- elsif($Part=~/(\w+)[\,\)]*\Z/i)
- {
- $ParamName = $1;
- }
- if(not $ParamName)
- {
- push(@Parts, $Part);
- next;
- }
- if($ItalicParams and not $TName_Tid{1}{$Part} and not $TName_Tid{2}{$Part})
- {
- if(($Parameter_Position ne "") and ($Part_Num == $Parameter_Position))
- {
- $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='focus_param'>$ParamName</span>$2!ig;
- }
- elsif($ColorParams)
- {
- $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='color_param'>$ParamName</span>$2!ig;
- }
- else
- {
- $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span style='font-style:italic;'>$ParamName</span>$2!ig;
- }
- }
- $Part_Styled = "<span style='white-space:nowrap;'>".$Part_Styled."</span>";
- push(@Parts, $Part_Styled);
- $Part_Num += 1;
- }
- $Signature = $Begin."<span class='int_p'>"."(".join(" ", @Parts).")"."</span>".$End;
- $Signature =~ s!\[\]![<span style='padding-left:2px;'>]</span>!g;
- $Signature =~ s!operator=!operator<span style='padding-left:2px'>=</span>!g;
- $Signature =~ s!(\[in-charge\]|\[not-in-charge\]|\[in-charge-deleting\])!<span style='color:Black;font-weight:normal;'>$1</span>!g;
- return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
-}
-
-sub get_Signature_Parts($$)
-{
- my ($Signature, $Comma) = @_;
- my @Parts = ();
- my $Bracket_Num = 0;
- my $Bracket2_Num = 0;
- my $Parameters = $Signature;
- if($Signature=~/&gt;|&lt;/)
- {
- $Parameters=~s/&gt;/>/g;
- $Parameters=~s/&lt;/</g;
- }
- my $Part_Num = 0;
- if($Parameters =~ s/.+?\((.*)\)(| const)\Z/$1/)
- {
- foreach my $Pos (0 .. length($Parameters) - 1)
- {
- my $Symbol = substr($Parameters, $Pos, 1);
- $Bracket_Num += 1 if($Symbol eq "(");
- $Bracket_Num -= 1 if($Symbol eq ")");
- $Bracket2_Num += 1 if($Symbol eq "<");
- $Bracket2_Num -= 1 if($Symbol eq ">");
- if($Symbol eq "," and $Bracket_Num==0 and $Bracket2_Num==0)
- {
- $Parts[$Part_Num] .= $Symbol if($Comma);
- $Part_Num += 1;
- }
- else
- {
- $Parts[$Part_Num] .= $Symbol;
- }
- }
- if($Signature=~/&gt;|&lt;/)
- {
- foreach my $Part (@Parts)
- {
- $Part=~s/\>/&gt;/g;
- $Part=~s/\</&lt;/g;
- }
- }
- return @Parts;
- }
- else
- {
- return ();
- }
-}
-
-my %TypeProblems_Kind=(
- "Added_Virtual_Function"=>1,
- "Withdrawn_Virtual_Function"=>1,
- "Virtual_Function_Position"=>1,
- "Virtual_Function_Redefinition"=>1,
- "Virtual_Function_Redefinition_B"=>1,
- "Size"=>1,
- "Added_Member_And_Size"=>1,
- "Added_Middle_Member_And_Size"=>1,
- "Withdrawn_Member_And_Size"=>1,
- "Withdrawn_Member"=>1,
- "Withdrawn_Middle_Member_And_Size"=>1,
- "Member_Rename"=>1,
- "Enum_Member_Value"=>1,
- "Enum_Member_Name"=>1,
- "Member_Type_And_Size"=>1,
- "Member_Type"=>1,
- "Member_BaseType_And_Size"=>1,
- "Member_BaseType"=>1,
- "Member_PointerLevel"=>1,
- "BaseType"=>1
-);
-
-my %InterfaceProblems_Kind=(
- "Added_Interface"=>1,
- "Withdrawn_Interface"=>1,
- "Function_Become_Static"=>1,
- "Function_Become_NonStatic"=>1,
- "Parameter_Type_And_Size"=>1,
- "Parameter_Type"=>1,
- "Parameter_BaseType_And_Size"=>1,
- "Parameter_BaseType"=>1,
- "Parameter_PointerLevel"=>1,
- "Return_Type_And_Size"=>1,
- "Return_Type"=>1,
- "Return_BaseType_And_Size"=>1,
- "Return_BaseType"=>1,
- "Return_PointerLevel"=>1,
- "Withdrawn_Parameter"=>1,
- "Added_Parameter"=>1
-);
-
-sub testSystem_cpp()
-{
- print "testing for C++ library changes\n";
- my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
-
- #Withdrawn_Parameter
- @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
- @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
- @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
-
- #Added_Parameter
- @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
- @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
- @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
-
- #Added_Virtual_Function
- @DataDefs_v1 = (@DataDefs_v1, "class type_test_added_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
- @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
-
- #added simple function
- @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_funcptr(FUNCPTR_TYPE*const** f);");
- @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
-
- #Withdrawn_Virtual_Function
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "class type_test_withdrawn_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
- @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
-
- #Virtual_Function_Position
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
-
- #virtual functions safe replace
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
-
- #virtual table changes
- @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};");
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
-
- @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};");
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
-
- #Virtual_Function_Redefinition
- @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};");
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func1(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func2(int param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
-
- @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};");
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func1(int param){\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func2(int param){\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func2(int param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
-
- #size change
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
-
- #Added_Member_And_Size
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
-
- #Method object changes
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
-
- #added bitfield
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
-
- #withdrawn bitfield
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
-
- #Added_Middle_Member_And_Size
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Member_Rename
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
-
- #Withdrawn_Member_And_Size
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
-
- #Withdrawn_Middle_Member_And_Size
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Enum_Member_Value
- @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
- @Sources_v1 = (@Sources_v1,
-"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
- @Sources_v2 = (@Sources_v2,
-"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- #Enum_Member_Name
- @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
- @Sources_v1 = (@Sources_v1,
-"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
- @Sources_v2 = (@Sources_v2,
-"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- #Member_Type_And_Size
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Member_Type
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
-
- #Member_BaseType
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
-
- #Member_PointerLevel_And_Size
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Member_PointerLevel
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
-
- #Added_Interface (function)
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int added_func_2(void *** param);");
- @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::added_func(type_test_added_interface param)\n{\n return param;\n}");
- @Sources_v2 = (@Sources_v2, "int added_func_2(void *** param)\n{\n return 0;\n}");
-
- #Added_Interface (global variable)
- @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};");
- @Sources_v1 = (@Sources_v1, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return i;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return type_test_added_variable::i;\n}");
- @Sources_v2 = (@Sources_v2, "int type_test_added_variable::i=0;");
-
- #Withdrawn_Interface
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func_2(void *** param);");
- @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::withdrawn_func(type_test_withdrawn_interface param)\n{\n return param;\n}");
- @Sources_v1 = (@Sources_v1, "int withdrawn_func_2(void *** param)\n{\n return 0;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
-
- #Function_Become_Static
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Function_Become_NonStatic
- @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};");
- @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}");
-
- @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};");
- @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}");
-
- #Parameter_Type_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
-
- #Parameter_Type
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
-
- #Parameter_BaseType
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
-
- #Parameter_PointerLevel_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
- @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
- @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
-
- #Parameter_PointerLevel
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
-
- #Return_Type_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
- @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
-
- #Return_Type
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
- @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
-
- #Return_BaseType
- @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetype(int param);");
- @Sources_v1 = (@Sources_v1, "int *func_return_basetype(int param)\n{\n int *x = new int[10];\n return x;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetype(int param);");
- @Sources_v2 = (@Sources_v2, "long long *func_return_basetype(int param)\n{\n long long *x = new long long[10];\n return x;\n}");
-
- #Return_PointerLevel_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
- @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
- @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}");
-
- #Return_PointerLevel
- @DataDefs_v1 = (@DataDefs_v1, "int* func_return_pointerlevel(int param);");
- @Sources_v1 = (@Sources_v1, "int* func_return_pointerlevel(int param)\n{\n int* x = new int[10];\n return x;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int **func_return_pointerlevel(int param);");
- @Sources_v2 = (@Sources_v2, "int **func_return_pointerlevel(int param)\n{\n int** x = new int*[10];\n return x;\n}");
-
- #typedef to anon struct
- @DataDefs_v1 = (@DataDefs_v1, "
-typedef struct
-{
-public:
- int i;
- long j;
- double k;
-} type_test_anon_typedef;
-int func_test_anon_typedef(type_test_anon_typedef param);");
- @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-typedef struct
-{
-public:
- int i;
- long j;
- double k;
- union {
- int dummy[256];
- struct {
- char q_skiptable[256];
- const char *p;
- int l;
- } p;
- };
-} type_test_anon_typedef;
-int func_test_anon_typedef(type_test_anon_typedef param);");
- @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
-
- #opaque type
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
-
- #internal function
- @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};");
- @Sources_v1 = (@Sources_v1, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
-
- @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};");
- @Sources_v2 = (@Sources_v2, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
-
- #starting versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
- @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\");");
-
- #Return_Type And Good Versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
- @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\");");
-
- #Return_Type and bad versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
- @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\");");
-
- #unnamed struct fields within structs
- @DataDefs_v1 = (@DataDefs_v1, "
-typedef struct {
- int a;
- struct {
- int b;
- float c;
- };
- int d;
-} type_test_unnamed;
-int func_test_unnamed(type_test_unnamed param);");
- @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-typedef struct {
- int a;
- struct {
- long double b;
- float c;
- };
- int d;
-} type_test_unnamed;
-int func_test_unnamed(type_test_unnamed param);");
- @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
-
- #constants
- @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
- @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
-
- @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
- @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
-
- #unions
- @DataDefs_v1 = (@DataDefs_v1, "
-union type_test_union {
- int a;
- struct {
- int b;
- float c;
- };
- int d;
-};
-int func_test_union(type_test_union param);");
- @Sources_v1 = (@Sources_v1, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-union type_test_union {
- int a;
- long double new_member;
- struct {
- int b;
- float c;
- };
- int d;
-};
-int func_test_union(type_test_union param);");
- @Sources_v2 = (@Sources_v2, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
-
- #typedefs
- @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
-
- #typedefs in member type
- @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);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
-
- @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);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
-
- 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_");
-}
-
-sub testSystem_c()
-{
- print "\ntesting for C library changes\n";
- my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
-
- #Withdrawn_Parameter
- @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
- @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
- @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
-
- #Added_Parameter
- @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
- @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
- @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
-
- #added function with typedef funcptr parameter
- @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f);");
- @Sources_v2 = (@Sources_v2, "int added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
-
- #added function with funcptr parameter
- @DataDefs_v2 = (@DataDefs_v2, "int added_function_param_funcptr(int(*func)(int, int));");
- @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(int(*func)(int, int))\n{\n return 0;\n}");
-
- #added function with no limited parameters
- @DataDefs_v2 = (@DataDefs_v2, "int added_function_nolimit_param(float p1, ...);");
- @Sources_v2 = (@Sources_v2, "int added_function_nolimit_param(float p1, ...)\n{\n return 0;\n}");
-
- #size change
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_type_size(struct type_test_size param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_type_size(struct type_test_size param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
-
- #Added_Member_And_Size
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_member(struct type_test_added_member param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_member(struct type_test_added_member param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
-
- #Added_Middle_Member_And_Size
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
- @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}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
- @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}");
-
- #Member_Rename
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
-
- #Withdrawn_Member_And_Size
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
-
- #Withdrawn_Middle_Member
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
- @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}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
- @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}");
-
- #Enum_Member_Value
- @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
- @Sources_v1 = (@Sources_v1,
-"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
- @Sources_v2 = (@Sources_v2,
-"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- #Enum_Member_Name
- @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
- @Sources_v1 = (@Sources_v1,
-"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
- @Sources_v2 = (@Sources_v2,
-"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
-{
- switch(param)
- {
- case 1:
- return 1;
- case 2:
- return 2;
- }
- return 0;
-}");
-
- #Member_Type_And_Size
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
- @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}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
- @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}");
-
- #Member_Type
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type(struct type_test_member_type param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type(struct type_test_member_type param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
-
- #Member_BaseType
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
-
- #Member_PointerLevel_And_Size
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
- @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}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
- @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}");
-
- #Member_PointerLevel
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
-
- #Added_Interface
- @DataDefs_v2 = (@DataDefs_v2, "int added_func(int param);");
- @Sources_v2 = (@Sources_v2, "int added_func(int param)\n{\n return param;\n}");
-
- #Withdrawn_Interface
- @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func(int param);");
- @Sources_v1 = (@Sources_v1, "int withdrawn_func(int param)\n{\n return param;\n}");
-
- #Parameter_Type_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
-
- #Parameter_Type
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
-
- #Parameter_BaseType (Typedef)
- @DataDefs_v1 = (@DataDefs_v1, "typedef int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "typedef const int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
-
- #Parameter_BaseType
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
-
- #Parameter_PointerLevel_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
- @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
- @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
-
- #Parameter_PointerLevel
- @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
-
- #Return_Type_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
- @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
-
- #Return_Type
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
- @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
-
- #Return_BaseType
- @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetypechange(int param);");
- @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}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetypechange(int param);");
- @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}");
-
- #Return_PointerLevel_And_Size
- @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
- @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
- @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}");
-
- #Return_PointerLevel
- @DataDefs_v1 = (@DataDefs_v1, "long long *func_return_pointerlevel(int param);");
- @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}");
-
- @DataDefs_v2 = (@DataDefs_v2, "long long **func_return_pointerlevel(int param);");
- @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}");
-
- #typedef to anon struct
- @DataDefs_v1 = (@DataDefs_v1, "
-typedef struct
-{
- int i;
- long j;
- double k;
-} type_test_anon_typedef;
-int func_test_anon_typedef(type_test_anon_typedef param);");
- @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-typedef struct
-{
- int i;
- long j;
- double k;
- union {
- int dummy[256];
- struct {
- char q_skiptable[256];
- const char *p;
- int l;
- } p;
- };
-} type_test_anon_typedef;
-int func_test_anon_typedef(type_test_anon_typedef param);");
- @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
-
- #opaque type
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_opaque(struct type_test_opaque param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_opaque(struct type_test_opaque param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
-
- #internal function
- @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};");
- @DataDefs_v1 = (@DataDefs_v1, "int func_test_internal(struct type_test_internal param, int param_2);");
- @Sources_v1 = (@Sources_v1, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
-
- @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};");
- @DataDefs_v2 = (@DataDefs_v2, "int func_test_internal(struct type_test_internal param, int param_2);");
- @Sources_v2 = (@Sources_v2, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
-
- #starting versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
- @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
- @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\");");
-
- #Return_Type and good versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
- @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\");");
-
- #Return_Type and bad versioning
- @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
- @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\");");
-
- @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
- @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\");");
-
- #unnamed struct/union fields within structs/unions
- @DataDefs_v1 = (@DataDefs_v1, "
-typedef struct {
- int a;
- union {
- int b;
- float c;
- };
- int d;
-} type_test_unnamed;
-int func_test_unnamed(type_test_unnamed param);");
- @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-typedef struct {
- int a;
- union {
- long double b;
- float c;
- };
- int d;
-} type_test_unnamed;
-int func_test_unnamed(type_test_unnamed param);");
- @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
-
- #constants
- @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
- @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
-
- @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
- @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
-
- #anon ptr typedef
- @DataDefs_v1 = (@DataDefs_v1, "
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-typedef struct {
- int a;
-} *type_test_anonptr_typedef;
-extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
-#ifdef __cplusplus
-}
-#endif");
- @Sources_v1 = (@Sources_v1, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-typedef struct {
- float a;
-} *type_test_anonptr_typedef;
-extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
-#ifdef __cplusplus
-}
-#endif");
- @Sources_v2 = (@Sources_v2, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
-
- #typedefs
- @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
- @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1.0;\n}");
-
- @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
- @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
-
- #typedefs in member type
- @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);");
- @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
-
- @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);");
- @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
-
- 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");
-}
-
-sub create_TestSuite($$$$$$$$)
-{
- my ($Dir, $Lang, $DataDefs_v1, $Sources_v1, $DataDefs_v2, $Sources_v2, $Opaque, $Private) = @_;
- my $Ext = ($Lang eq "C++")?"cpp":"c";
- my $Gcc = ($Lang eq "C++")?"g++":"gcc";
- #creating test suite
- my $Path_v1 = "$Dir/lib_abi_changes_test.v1";
- my $Path_v2 = "$Dir/lib_abi_changes_test.v2";
-
- system("rm", "-fr", $Path_v1, $Path_v2);
- system("mkdir", "-p", $Path_v1, $Path_v2);
-
- writeFile("$Path_v1/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
- writeFile("$Path_v1/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v1."\n");
- writeFile("$Path_v1/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v1."\n");
- 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");
-
- writeFile("$Path_v2/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
- writeFile("$Path_v2/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v2."\n");
- writeFile("$Path_v2/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v2."\n");
- 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");
-
- system("$Gcc $Path_v1/lib_abi_changes_test.h");
- if($?)
- {
- print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.h\'\n";
- return;
- }
- system("$Gcc -Wl,--version-script $Path_v1/version -shared $Path_v1/lib_abi_changes_test.$Ext -o $Path_v1/lib_abi_changes_test.so");
- if($?)
- {
- print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.$Ext\'\n";
- return;
- }
- system("$Gcc $Path_v2/lib_abi_changes_test.h");
- if($?)
- {
- print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.h\'\n";
- return;
- }
- system("$Gcc -Wl,--version-script $Path_v2/version -shared $Path_v2/lib_abi_changes_test.$Ext -o $Path_v2/lib_abi_changes_test.so");
- if($?)
- {
- print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.$Ext\'\n";
- return;
- }
-
- #running abi-compliance-checker
- system("$0 -l lib_$Dir -d1 $Dir/descriptor.v1 -d2 $Dir/descriptor.v2");
-}
-
-sub writeFile($$)
-{
- my ($Path, $Content) = @_;
- return if(not $Path);
- open (FILE, ">".$Path) || die ("Can't open file $Path\n");
- print FILE $Content;
- close(FILE);
-}
-
-sub readFile($)
-{
- my $Path = $_[0];
- return "" if(not $Path or not -f $Path);
- open (FILE, $Path);
- my $Content = join("\n", <FILE>);
- close(FILE);
- return toUnix($Content);
-}
-
-sub toUnix($)
-{
- my $Text = $_[0];
- $Text=~s/\r//g;
- return $Text;
-}
-
-sub getArch()
-{
- my $Arch = $ENV{"CPU"};
- if(not $Arch)
- {
- $Arch = `uname -m`;
- chomp($Arch);
- }
- if(not $Arch)
- {
- $Arch = `uname -p`;
- chomp($Arch);
- }
- $Arch = "x86" if($Arch =~ /i[3-7]86/);
- return $Arch;
-}
-
-sub get_Report_Header()
-{
- 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";
- return "<!--Header-->\n".$Report_Header."<!--Header_End-->\n";
-}
-
-sub get_SourceInfo()
-{
- 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";
- foreach my $Header_Dest (sort {lc($Headers{1}{$a}{"Name"}) cmp lc($Headers{1}{$b}{"Name"})} keys(%{$Headers{1}}))
- {
- my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
- my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
- my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
- my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
- $CheckedHeaders .= "<span class='header_list_elem'>$Header_Name"."$Dest_Comment</span><br/>\n";
- }
- $CheckedHeaders .= "<!--Checked_Headers_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
- 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";
- foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$SoNames_All{1}}))
- {
- $CheckedLibs .= "<span class='solib_list_elem'>$Library</span><br/>\n";
- }
- $CheckedLibs .= "<!--Checked_Libs_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
- return $CheckedHeaders.$CheckedLibs;
-}
-
-sub get_TypeProblems_Count($$)
-{
- my ($TypeChanges, $TargetPriority) = @_;
- my $Type_Problems_Count = 0;
- foreach my $TypeName (sort keys(%{$TypeChanges}))
- {
- my %Kinds_Target = ();
- foreach my $Kind (keys(%{$TypeChanges->{$TypeName}}))
- {
- foreach my $Location (keys(%{$TypeChanges->{$TypeName}{$Kind}}))
- {
- my $Priority = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Priority"};
- next if($Priority ne $TargetPriority);
- my $Target = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Target"};
- next if($Kinds_Target{$Kind}{$Target});
- $Kinds_Target{$Kind}{$Target} = 1;
- $Type_Problems_Count += 1;
- }
- }
- }
- return $Type_Problems_Count;
-}
-
-sub get_Summary()
-{
- 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);
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
- {
- if($InterfaceProblems_Kind{$Kind})
- {
- foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- if($Kind eq "Added_Interface")
- {
- $Added += 1;
- }
- elsif($Kind eq "Withdrawn_Interface")
- {
- $Withdrawn += 1;
- }
- else
- {
- if($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "High")
- {
- $I_Problems_High += 1;
- }
- elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Medium")
- {
- $I_Problems_Medium += 1;
- }
- elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Low")
- {
- $I_Problems_Low += 1;
- }
- }
- }
- }
- }
- }
-
- my (%TypeChanges, %Type_MaxPriority);
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
- {
- if($TypeProblems_Kind{$Kind})
- {
- foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
- my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
- %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
- $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
- }
- }
- }
- }
-
- foreach my $Type_Name (keys(%TypeChanges))
- {
- foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
- {
- foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
- {
- my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
- if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
- {
- delete($TypeChanges{$Type_Name}{$Kind}{$Location});
- }
- }
- }
- }
-
- $T_Problems_High = get_TypeProblems_Count(\%TypeChanges, "High");
- $T_Problems_Medium = get_TypeProblems_Count(\%TypeChanges, "Medium");
- $T_Problems_Low = get_TypeProblems_Count(\%TypeChanges, "Low");
-
- #summary
- my $Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Summary</h2><hr/>";
- $Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
-
-
- my $Checked_Headers_Link = "0";
- $Checked_Headers_Link = "<a href='#Checked_Headers' style='color:Blue;'>".keys(%{$Headers{1}})."</a>" if(keys(%{$Headers{1}})>0);
- $Summary .= "<tr><td class='table_header summary_item'>Total header files checked</td><td class='summary_item_value'>$Checked_Headers_Link</td></tr>";
-
- my $Checked_Libs_Link = "0";
- $Checked_Libs_Link = "<a href='#Checked_Libs' style='color:Blue;'>".keys(%{$SoNames_All{1}})."</a>" if(keys(%{$SoNames_All{1}})>0);
- $Summary .= "<tr><td class='table_header summary_item'>Total shared objects checked</td><td class='summary_item_value'>$Checked_Libs_Link</td></tr>";
- $Summary .= "<tr><td class='table_header summary_item'>Total interfaces / types checked</td><td class='summary_item_value'>".keys(%CheckedInterfaces)." / ".keys(%CheckedTypes)."</td></tr>";
-
- my $Verdict = "<span style='color:Green;'><b>Compatible</b></span>";
- $Verdict = "<span style='color:Red;'><b>Incompatible</b></span>" if(($Withdrawn>0) or ($I_Problems_High>0) or ($T_Problems_High>0));
- $Summary .= "<tr><td class='table_header summary_item'>Verdict</td><td class='summary_item_value'>$Verdict</td></tr>";
-
- $Summary .= "</table>\n";
-
- #problem summary
- my $Problem_Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problem Summary</h2><hr/>";
- $Problem_Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
-
- my $Added_Link = "0";
- $Added_Link = "<a href='#Added' style='color:Blue;'>$Added</a>" if($Added>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Added interfaces</td><td class='summary_item_value'>$Added_Link</td></tr>";
-
- my $WIthdrawn_Link = "0";
- $WIthdrawn_Link = "<a href='#Withdrawn' style='color:Blue;'>$Withdrawn</a>" if($Withdrawn>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Withdrawn interfaces</td><td class='summary_item_value'>$WIthdrawn_Link</td></tr>";
-
- my $TH_Link = "0";
- $TH_Link = "<a href='#Type_Problems_High' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
- $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>";
-
- my $TM_Link = "0";
- $TM_Link = "<a href='#Type_Problems_Medium' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$TM_Link</td></tr>";
-
- my $TL_Link = "0";
- $TL_Link = "<a href='#Type_Problems_Low' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$TL_Link</td></tr>";
-
- my $IH_Link = "0";
- $IH_Link = "<a href='#Interface_Problems_High' style='color:Blue;'>$I_Problems_High</a>" if($I_Problems_High>0);
- $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>";
-
- my $IM_Link = "0";
- $IM_Link = "<a href='#Interface_Problems_Medium' style='color:Blue;'>$I_Problems_Medium</a>" if($I_Problems_Medium>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$IM_Link</td></tr>";
-
- my $IL_Link = "0";
- $IL_Link = "<a href='#Interface_Problems_Low' style='color:Blue;'>$I_Problems_Low</a>" if($I_Problems_Low>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$IL_Link</td></tr>";
-
- my $ChangedConstants_Link = "0";
- $ChangedConstants_Link = "<a href='#Constants' style='color:Blue;'>".keys(%ConstantProblems)."</a>" if(keys(%ConstantProblems)>0);
- $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Constants Problems</td><td class='summary_item_value'>$ChangedConstants_Link</td></tr>";
-
- $Problem_Summary .= "</table>\n";
- return "<!--Summary-->\n".$Summary.$Problem_Summary."<!--Summary_End-->\n";
-}
-
-sub get_Report_ChangedConstants()
-{
- my ($CHANGED_CONSTANTS, %HeaderConstant);
- foreach my $Name (keys(%ConstantProblems))
- {
- $HeaderConstant{$ConstantProblems{$Name}{"Header"}}{$Name} = 1;
- }
- my $Constants_Number = 0;
- foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%HeaderConstant))
- {
- $CHANGED_CONSTANTS .= "<span class='header_name'>$HeaderName</span><br/>\n";
- foreach my $Name (sort {lc($a) cmp lc($b)} keys(%{$HeaderConstant{$HeaderName}}))
- {
- $Constants_Number += 1;
- my $Old_Value = htmlSpecChars($ConstantProblems{$Name}{"Old_Value"});
- my $New_Value = htmlSpecChars($ConstantProblems{$Name}{"New_Value"});
- 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>.";
- my $Effect = "If application uses this constant as a parameter of some interface than its execution may change.";
- 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";
- $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";
- $CHANGED_CONSTANTS = insertIDs($CHANGED_CONSTANTS);
- }
- $CHANGED_CONSTANTS .= "<br/>\n";
- }
- if($CHANGED_CONSTANTS)
- {
- $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";
- }
- return $CHANGED_CONSTANTS;
-}
-
-sub get_Report_Added()
-{
- my $ADDED_INTERFACES;
- #added interfaces
- my %FuncAddedInHeaderLib;
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
- {
- foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- if($Kind eq "Added_Interface")
- {
- $FuncAddedInHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"New_SoName"}}{$Interface} = 1;
- last;
- }
- }
- }
- }
- my $Added_Number = 0;
- foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncAddedInHeaderLib))
- {
- foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncAddedInHeaderLib{$HeaderName}}))
- {
- if($HeaderName)
- {
- $ADDED_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
- }
- else
- {
- $ADDED_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
- }
- foreach my $Interface (sort {lc($CompatProblems{$a}{"Added_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Added_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncAddedInHeaderLib{$HeaderName}{$SoName}}))
- {
- $Added_Number += 1;
- my $SubReport = "";
- my $Signature = $CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}{"Signature"};
- if($Interface =~ /\A_Z/)
- {
- if($Signature)
- {
- $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");
- }
- else
- {
- $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
- }
- }
- else
- {
- if($Signature)
- {
- $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
- }
- else
- {
- $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
- }
- }
- $ADDED_INTERFACES .= $SubReport;
- }
- $ADDED_INTERFACES .= "<br/>\n";
- }
- }
- if($ADDED_INTERFACES)
- {
- $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";
- }
- return $ADDED_INTERFACES;
-}
-
-sub get_Report_Withdrawn()
-{
- my $WITHDRAWN_INTERFACES;
- #withdrawn interfaces
- my %FuncWithdrawnFromHeaderLib;
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
- {
- foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- if($Kind eq "Withdrawn_Interface")
- {
- $FuncWithdrawnFromHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"}}{$Interface} = 1;
- last;
- }
- }
- }
- }
- my $Withdrawn_Number = 0;
- foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncWithdrawnFromHeaderLib))
- {
- foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}}))
- {
- if($HeaderName)
- {
- $WITHDRAWN_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
- }
- else
- {
- $WITHDRAWN_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
- }
- foreach my $Interface (sort {lc($CompatProblems{$a}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}{$SoName}}))
- {
- $Withdrawn_Number += 1;
- my $SubReport = "";
- my $Signature = $CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"};
- if($Interface =~ /\A_Z/)
- {
- if($Signature)
- {
- $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");
- }
- else
- {
- $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
- }
- }
- else
- {
- if($Signature)
- {
- $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
- }
- else
- {
- $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
- }
- }
- $WITHDRAWN_INTERFACES .= $SubReport;
- }
- $WITHDRAWN_INTERFACES .= "<br/>\n";
- }
- }
- if($WITHDRAWN_INTERFACES)
- {
- $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";
- }
- return $WITHDRAWN_INTERFACES;
-}
-
-sub get_Report_InterfaceProblems($)
-{
- my $TargetPriority = $_[0];
- my ($INTERFACE_PROBLEMS, %FuncHeaderLib);
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
- {
- if($InterfaceProblems_Kind{$Kind} and ($Kind ne "Added_Interface") and ($Kind ne "Withdrawn_Interface"))
- {
- foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- my $SoName = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"};
- my $HeaderName = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
- $FuncHeaderLib{$HeaderName}{$SoName}{$Interface} = 1;
- last;
- }
- }
- }
- }
- my $Problems_Number = 0;
- #interface problems
- foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncHeaderLib))
- {
- foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncHeaderLib{$HeaderName}}))
- {
- my $HEADER_LIB_REPORT = "";
- foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$FuncHeaderLib{$HeaderName}{$SoName}}))
- {
- my $Signature = "";
- my $InterfaceProblemsReport = "";
- my $ProblemNum = 1;
- foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
- {
- foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- my $Incompatibility = "";
- my $Effect = "";
- my $Old_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"});
- my $New_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"});
- my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
- my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
- my $Old_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Size"};
- my $New_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Size"};
- my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
- my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
- my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
- $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"} if(not $Signature);
- next if($Priority ne $TargetPriority);
- if($Kind eq "Function_Become_Static")
- {
- $Incompatibility = "Function become <b>static</b>.\n";
- $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
- }
- elsif($Kind eq "Function_Become_NonStatic")
- {
- $Incompatibility = "Function become <b>non-static</b>.\n";
- $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
- }
- elsif($Kind eq "Parameter_Type_And_Size")
- {
- $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";
- $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
- }
- elsif($Kind eq "Parameter_Type")
- {
- $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";
- $Effect = "Replacement of parameter data type may indicate a change in the semantic meaning of this parameter.";
- }
- elsif($Kind eq "Withdrawn_Parameter")
- {
- $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been withdrawn from the interface signature.\n";
- $Effect = "This parameter will be ignored by the interface.";
- }
- elsif($Kind eq "Added_Parameter")
- {
- $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been added to the interface signature.\n";
- $Effect = "This parameter will not be initialized by applications.";
- }
- elsif($Kind eq "Parameter_BaseType_And_Size")
- {
- if($InitialType_Type eq "Pointer")
- {
- $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";
- $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
- }
- else
- {
- $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";
- $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
- }
- }
- elsif($Kind eq "Parameter_BaseType")
- {
- if($InitialType_Type eq "Pointer")
- {
- $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";
- $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
- }
- else
- {
- $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";
- $Effect = "Replacement of parameter base type may indicate a change in the semantic meaning of this parameter.";
- }
- }
- elsif($Kind eq "Parameter_PointerLevel")
- {
- $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";
- $Effect = "Possible incorrect initialization of $Parameter_Position_Str parameter <b>$Target</b> by applications.";
- }
- elsif($Kind eq "Return_Type_And_Size")
- {
- $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";
- $Effect = "Applications will get a different return value and execution may change.";
- }
- elsif($Kind eq "Return_Type")
- {
- $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";
- $Effect = "Replacement of return type may indicate a change in its semantic meaning.";
- }
- elsif($Kind eq "Return_BaseType_And_Size")
- {
- $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";
- $Effect = "Applications will get a different return value and execution may change.";
- }
- elsif($Kind eq "Return_BaseType")
- {
- $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";
- $Effect = "Replacement of return base type may indicate a change in its semantic meaning.";
- }
- elsif($Kind eq "Return_PointerLevel")
- {
- $Incompatibility = "Type pointer level of return value has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
- $Effect = "Applications will get a different return value and execution may change.";
- }
- if($Incompatibility)
- {
- $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";
- $ProblemNum += 1;
- $Problems_Number += 1;
- }
- }
- }
- $ProblemNum -= 1;
- if($InterfaceProblemsReport)
- {
- if($Interface =~ /\A_Z/)
- {
- if($Signature)
- {
- $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";
- }
- else
- {
- $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
- }
- }
- else
- {
- if($Signature)
- {
- $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
- }
- else
- {
- $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
- }
- }
- $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";
- $HEADER_LIB_REPORT = insertIDs($HEADER_LIB_REPORT);
- }
- }
- if($HEADER_LIB_REPORT)
- {
- $INTERFACE_PROBLEMS .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n".$HEADER_LIB_REPORT."<br/>";
- }
- }
- }
- if($INTERFACE_PROBLEMS)
- {
- $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";
- }
- return $INTERFACE_PROBLEMS;
-}
-
-sub get_Report_TypeProblems($)
-{
- my $TargetPriority = $_[0];
- my ($TYPE_PROBLEMS, %TypeHeader, %TypeChanges, %Type_MaxPriority) = ();
- foreach my $Interface (sort keys(%CompatProblems))
- {
- foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
- {
- if($TypeProblems_Kind{$Kind})
- {
- foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
- my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
- my $Type_Header = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
- %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
- $TypeHeader{$Type_Header}{$Type_Name} = 1;
- $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
- }
- }
- }
- }
- foreach my $Type_Name (keys(%TypeChanges))
- {
- foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
- {
- foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
- {
- my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
- if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
- {
- delete($TypeChanges{$Type_Name}{$Kind}{$Location});
- }
- }
- }
- }
- my $Problems_Number = 0;
- foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%TypeHeader))
- {
- my $HEADER_REPORT = "";
- foreach my $TypeName (sort {lc($a) cmp lc($b)} keys(%{$TypeHeader{$HeaderName}}))
- {
- my $ProblemNum = 1;
- my $TypeProblemsReport = "";
- my %Kinds_Locations = ();
- my %Kinds_Target = ();
- foreach my $Kind (keys(%{$TypeChanges{$TypeName}}))
- {
- foreach my $Location (keys(%{$TypeChanges{$TypeName}{$Kind}}))
- {
- my $Priority = $TypeChanges{$TypeName}{$Kind}{$Location}{"Priority"};
- next if($Priority ne $TargetPriority);
- $Kinds_Locations{$Kind}{$Location} = 1;
- my $Incompatibility = "";
- my $Effect = "";
- my $Target = $TypeChanges{$TypeName}{$Kind}{$Location}{"Target"};
- next if($Kinds_Target{$Kind}{$Target});
- $Kinds_Target{$Kind}{$Target} = 1;
- my $Old_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Value"});
- my $New_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"New_Value"});
- my $Old_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Size"};
- my $New_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"New_Size"};
- my $Type_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"Type_Type"};
- my $InitialType_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"InitialType_Type"};
-
- if($Kind eq "Added_Virtual_Function")
- {
- $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.";
- $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
- }
- elsif($Kind eq "Withdrawn_Virtual_Function")
- {
- $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.";
- $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
- }
- elsif($Kind eq "Virtual_Function_Position")
- {
- $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.";
- $Effect = "Call of this virtual method will result in crash of application.";
- }
- elsif($Kind eq "Virtual_Function_Redefinition")
- {
- $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>";
- $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>";
- }
- elsif($Kind eq "Virtual_Function_Redefinition_B")
- {
- $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>";
- $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>";
- }
- elsif($Kind eq "Size")
- {
- $Incompatibility = "Size of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b> bytes.";
- $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>";
- }
- elsif($Kind eq "BaseType")
- {
- $Incompatibility = "Base of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
- $Effect = "Possible incorrect initialization of interface parameters by applications.";
- }
- elsif($Kind eq "Added_Member_And_Size")
- {
- $Incompatibility = "Member <b>$Target</b> has been added to this type.";
- $Effect = "The size of the inclusive type has been changed.";
- }
- elsif($Kind eq "Added_Middle_Member_And_Size")
- {
- $Incompatibility = "Member <b>$Target</b> has been added between the first member and the last member of this structural type.";
- $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.";
- }
- elsif($Kind eq "Member_Rename")
- {
- $Incompatibility = "Member <b>$Target</b> has been renamed to <b>$New_Value</b>.";
- $Effect = "Renaming of a member in a structural data type may indicate a change in the semantic meaning of the member.";
- }
- elsif($Kind eq "Withdrawn_Member_And_Size")
- {
- $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
- $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.";
- }
- elsif($Kind eq "Withdrawn_Member")
- {
- $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
- $Effect = "Applications will access incorrect memory when attempting to access this member.";
- }
- elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
- {
- $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
- $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.";
- }
- elsif($Kind eq "Withdrawn_Middle_Member")
- {
- $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
- $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.";
- }
- elsif($Kind eq "Enum_Member_Value")
- {
- $Incompatibility = "Value of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
- $Effect = "Applications may execute another branch of library code.";
- }
- elsif($Kind eq "Enum_Member_Name")
- {
- $Incompatibility = "Name of member with value <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
- $Effect = "Applications may execute another branch of library code.";
- }
- elsif($Kind eq "Member_Type_And_Size")
- {
- $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>.";
- $Effect = "Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.";
- }
- elsif($Kind eq "Member_Type")
- {
- $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>.";
- $Effect = "Replacement of the member data type may indicate a change in the semantic meaning of the member.";
- }
- elsif($Kind eq "Member_BaseType_And_Size")
- {
- if($InitialType_Type eq "Pointer")
- {
- $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>.";
- $Effect = "Possible access of applications to incorrect memory via member pointer.";
- }
- else
- {
- $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>.";
- $Effect = "Layout of structure members has been changed and therefore members in higher positions in structure definition may be incorrectly accessed by applications.";
- }
- }
- elsif($Kind eq "Member_BaseType")
- {
- if($InitialType_Type eq "Pointer")
- {
- $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>.";
- $Effect = "Possible access of applications to incorrect memory via member pointer.";
- }
- else
- {
- $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>.";
- $Effect = "Replacement of member base type may indicate a change in the semantic meaning of this member.";
- }
- }
- elsif($Kind eq "Member_PointerLevel")
- {
- $Incompatibility = "Type pointer level of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
- $Effect = "Possible incorrect initialization of member <b>$Target</b> by applications.";
- }
- if($Incompatibility)
- {
- $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";
- $ProblemNum += 1;
- $Problems_Number += 1;
- $Kinds_Locations{$Kind}{$Location} = 1;
- }
- }
- }
- $ProblemNum -= 1;
- if($TypeProblemsReport)
- {
- my ($Affected_Interfaces_Header, $Affected_Interfaces) = getAffectedInterfaces($TypeName, \%Kinds_Locations);
- $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";
- $HEADER_REPORT = insertIDs($HEADER_REPORT);
- }
- }
- if($HEADER_REPORT)
- {
- $TYPE_PROBLEMS .= "<span class='header_name'>$HeaderName</span><br/>\n".$HEADER_REPORT."<br/>";
- }
- }
- if($TYPE_PROBLEMS)
- {
- my $Notations = "";
- if($TYPE_PROBLEMS =~ /'RetVal|'Obj/)
- {
- my @Notations_Array = ();
- if($TYPE_PROBLEMS =~ /'RetVal/)
- {
- @Notations_Array = (@Notations_Array, "<span style='color:#444444;padding-left:5px;'><b>RetVal</b></span> - function's return value");
- }
- if($TYPE_PROBLEMS =~ /'Obj/)
- {
- @Notations_Array = (@Notations_Array, "<span style='color:#444444;'><b>Obj</b></span> - method's object (C++)");
- }
- $Notations = "Shorthand notations: ".join("; ", @Notations_Array).".<br/>\n";
- }
- $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";
- }
- return $TYPE_PROBLEMS;
-}
-
-my $ContentSpanStart_2 = "<span style='line-height:25px;' class=\"section_2\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
-
-sub getAffectedInterfaces($$)
-{
- my ($Target_TypeName, $Kinds_Locations) = @_;
- my ($Affected_Interfaces_Header, $Affected_Interfaces, %FunctionNumber) = ();
- foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%CompatProblems))
- {
- next if(($Interface =~ /C2/) or ($Interface =~ /D2/) or ($Interface =~ /D0/));
- next if(keys(%FunctionNumber)>1000);
- my $FunctionProblem = "";
- my $MinPath_Length = "";
- my $MaxPriority = 0;
- my $Location_Last = "";
- foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
- {
- foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
- {
- next if(not $Kinds_Locations->{$Kind}{$Location});
- my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
- my $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"};
- my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
- my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
- if($Type_Name eq $Target_TypeName)
- {
- $FunctionNumber{$Interface} = 1;
- my $Path_Length = 0;
- while($Location =~ /\-\>/g){$Path_Length += 1;}
- 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 =~ /\-\>/))
- {
- $MinPath_Length = $Path_Length;
- $MaxPriority = $Priority_Value{$Priority};
- $Location_Last = $Location;
- my $Description = get_AffectDescription($Interface, $Kind, $Location);
- $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;'>&nbsp;</div>\n";
- }
- }
- }
- }
- $Affected_Interfaces .= $FunctionProblem;
- }
- $Affected_Interfaces .= "and other...<br/>" if(keys(%FunctionNumber)>5000);
- if($Affected_Interfaces)
- {
- $Affected_Interfaces_Header = $ContentSpanStart_2."[+] affected interfaces (".keys(%FunctionNumber).")".$ContentSpanEnd;
- $Affected_Interfaces = $ContentDivStart.$Affected_Interfaces.$ContentDivEnd;
- }
- return ($Affected_Interfaces_Header, $Affected_Interfaces);
-}
-
-my %Kind_TypeStructureChanged=(
- "Size"=>1,
- "Added_Member_And_Size"=>1,
- "Added_Middle_Member_And_Size"=>1,
- "Member_Rename"=>1,
- "Withdrawn_Member_And_Size"=>1,
- "Withdrawn_Member"=>1,
- "Withdrawn_Middle_Member_And_Size"=>1,
- "Enum_Member_Value"=>1,
- "Enum_Member_Name"=>1,
- "Member_Type_And_Size"=>1,
- "Member_Type"=>1,
- "Member_BaseType_And_Size"=>1,
- "Member_BaseType"=>1,
- "Member_PointerLevel"=>1,
- "BaseType"=>1
-);
-
-my %Kind_VirtualTableChanged=(
- "Added_Virtual_Function"=>1,
- "Withdrawn_Virtual_Function"=>1,
- "Virtual_Function_Position"=>1,
- "Virtual_Function_Redefinition"=>1,
- "Virtual_Function_Redefinition_B"=>1
-);
-
-sub get_AffectDescription($$$)
-{
- my ($Interface, $Kind, $Location) = @_;
- my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
- my $Old_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"};
- my $New_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"};
- my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
- my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
- my $Parameter_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Name"};
- my $Parameter_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Type_Name"};
- my $Member_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Member_Type_Name"};
- my $Object_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Object_Type_Name"};
- my $Return_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Return_Type_Name"};
- my $Start_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Start_Type_Name"};
- my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
- my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
- my @Sentence_Parts = ();
- my $Location_To_Type = $Location;
- $Location_To_Type =~ s/\-\>[^>]+?\Z//;
- if($Kind_VirtualTableChanged{$Kind})
- {
- if($Kind eq "Virtual_Function_Redefinition")
- {
- @Sentence_Parts = (@Sentence_Parts, "This method become virtual and will be called instead of redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."'.");
- }
- elsif($Kind eq "Virtual_Function_Redefinition_B")
- {
- @Sentence_Parts = (@Sentence_Parts, "This method become non-virtual and redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."' will be called instead of it.");
- }
- else
- {
- @Sentence_Parts = (@Sentence_Parts, "Call of this virtual method will result in crash of application because the layout of virtual table has been changed.");
- }
- }
- elsif($Kind_TypeStructureChanged{$Kind})
- {
- if($Location_To_Type =~ /RetVal/)
- {#return value
- if($Location_To_Type =~ /\-\>/)
- {
- @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in return value");
- }
- else
- {
- @Sentence_Parts = (@Sentence_Parts, "Return value");
- }
- }
- elsif($Location_To_Type =~ /Obj/)
- {#object
- if($Location_To_Type =~ /\-\>/)
- {
- @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in the object of this method");
- }
- else
- {
- @Sentence_Parts = (@Sentence_Parts, "Object");
- }
- }
- else
- {#parameters
- if($Location_To_Type =~ /\-\>/)
- {
- @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' of $Parameter_Position_Str parameter");
- }
- else
- {
- @Sentence_Parts = (@Sentence_Parts, "$Parameter_Position_Str parameter");
- }
- if($Parameter_Name)
- {
- @Sentence_Parts = (@Sentence_Parts, "\'$Parameter_Name\'");
- }
- if($InitialType_Type eq "Pointer")
- {
- @Sentence_Parts = (@Sentence_Parts, "(pointer)");
- }
- }
- if($Start_Type_Name eq $Type_Name)
- {
- @Sentence_Parts = (@Sentence_Parts, "has type \'$Type_Name\'.");
- }
- else
- {
- @Sentence_Parts = (@Sentence_Parts, "has base type \'$Type_Name\'.");
- }
- }
- return join(" ", @Sentence_Parts);
-}
-
-sub create_HtmlReport()
-{
- my $CssStyles = "<style type=\"text/css\">
- body{font-family:Arial;}
- hr{color:Black;background-color:Black;height:1px;border:0;}
- span.section{font-weight:bold;cursor:pointer;margin-left:7px;font-size:16px;font-family:Arial;color:#003E69;}
- span:hover.section{color:#336699;}
- span.section_2{cursor:pointer;margin-left:7px;font-size:14px;font-family:Arial;color:#cc3300;}
- span.extension{font-weight:100;font-size:16px;}
- span.problem_exact_location{color:Red;font-size:14px;}
- span.header_name{color:#cc3300;font-size:14px;font-family:Arial;font-weight:bold;}
- span.header_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
- span.solib_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
- span.solib_name{color:Green;font-size:14px;font-family:Arial;font-weight:bold;}
- span.interface_name{font-weight:bold;font-size:16px;font-family:Arial;color:#003E69;margin-left:7px;}
- span.interface_name_black{font-weight:bold;font-size:15px;font-family:Arial;color:#333333;}
- span.problem_title{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
- span.problem_sub_title{color:#333333;text-decoration:none;font-weight:bold;font-size:13px;font-family:Verdana;}
- span.problem_body{color:Black;font-size:14px;}
- span.int_p{font-weight:normal;}
- span.affect_description{padding-left:30px;font-size:14px;font-style:italic;line-height:13px;}
- table.problems_table{line-height:16px;margin-left:15px;margin-top:3px;border-collapse:collapse;}
- table.problems_table td{border-style:solid;border-color:Gray;border-width:1px;}
- td.table_header{background-color:#eeeeee;}
- td.summary_item{font-size:15px;font-family:Arial;text-align:left;}
- td.summary_item_value{padding-left:5px;padding-right:5px;width:35px;text-align:right;}
- span.problem_num{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
- span.mangled{padding-left:15px;font-size:13px;cursor:text;color:#444444;}
- span.symver{color:#555555;font-size:13px;white-space:nowrap;}
- span.color_param{font-style:italic;color:Brown;}
- span.focus_param{font-style:italic;color:Red;}</style>";
-
- my $JScripts = "<script type=\"text/javascript\" language=\"JavaScript\">
- function showContent(header, id) {
- e = document.getElementById(id);
- if(e.style.display == 'none')
- {
- e.style.display = '';
- e.style.visibility = 'visible';
- header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[&minus;]\");
- }
- else
- {
- e.style.display = 'none';
- e.style.visibility = 'hidden';
- header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[+]\");
- }
- }</script>";
-
- 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\" />
- <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 &nbsp;</i></div>\n<div style='height:999px;'></div>\n</body></html>");
-}
-
-sub trivialCmp($$)
-{
- if(int($_[0]) > int($_[1]))
- {
- return 1;
- }
- elsif($_[0] eq $_[1])
- {
- return 0;
- }
- else
- {
- return -1;
- }
-}
-
-sub addArrows($)
-{
- my $Text = $_[0];
- #$Text =~ s/\-\>/&#8594;/g;
- $Text =~ s/\-\>/&minus;&gt;/g;
- return $Text;
-}
-
-sub insertIDs($)
-{
- my $Text = $_[0];
- while($Text =~ /CONTENT_ID/)
- {
- if(int($Content_Counter)%2)
- {
- $ContentID -= 1;
- }
- $Text =~ s/CONTENT_ID/c_$ContentID/;
- $ContentID += 1;
- $Content_Counter += 1;
- }
- return $Text;
-}
-
-sub restrict_num_decimal_digits
-{
- my $num=shift;
- my $digs_to_cut=shift;
-
- if ($num=~/\d+\.(\d){$digs_to_cut,}/)
- {
- $num=sprintf("%.".($digs_to_cut-1)."f", $num);
- }
- return $num;
-}
-
-sub parse_constants()
-{
- my $CurHeader = "";
- foreach my $String (split("\n", $ConstantsSrc{$Version}))
- {#detecting public and private constants using sources
- if($String=~/#[ \t]+\d+[ \t]+\"(.+)\"/)
- {
- $CurHeader=$1;
- }
- if($String=~/\#[ \t]*define[ \t]+([_A-Z]+)[ \t]+(.*)[ \t]*\Z/)
- {
- my ($Name, $Value) = ($1, $2);
- if(not $Constants{$Version}{$Name}{"Access"})
- {
- $Constants{$Version}{$Name}{"Access"} = "public";
- $Constants{$Version}{$Name}{"Value"} = $Value;
- $Constants{$Version}{$Name}{"Header"} = get_FileName($CurHeader);
- }
- }
- elsif($String=~/\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/)
- {
- my $Name = $1;
- $Constants{$Version}{$Name}{"Access"} = "private";
- }
- }
- foreach my $Constant (keys(%{$Constants{$Version}}))
- {
- if(($Constants{$Version}{$Constant}{"Access"} eq "private") or not $Constants{$Version}{$Constant}{"Value"}
- or $Constant=~/_h\Z/i)
- {
- delete($Constants{$Version}{$Constant});
- }
- else
- {
- delete($Constants{$Version}{$Constant}{"Access"});
- }
- }
-}
-
-sub mergeConstants()
-{
- return if(defined $AppPath);
- foreach my $Constant (keys(%{$Constants{1}}))
- {
- my $Old_Value = $Constants{1}{$Constant}{"Value"};
- my $New_Value = $Constants{2}{$Constant}{"Value"};
- my $Header = $Constants{1}{$Constant}{"Header"};
- if($New_Value and $Old_Value and ($New_Value ne $Old_Value))
- {
- %{$ConstantProblems{$Constant}} = (
- "Old_Value"=>$Old_Value,
- "New_Value"=>$New_Value,
- "Header"=>$Header
- );
- }
- }
-}
-
-sub mergeHeaders_Separately()
-{
- system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
- system("rm", "-fr", $ERR_PATH{1}, $ERR_PATH{2});
- my ($Header_Num, $Prev_Header_Length) = (0, 0);
- my $All_Count = keys(%{$Headers{1}});
- foreach my $Header_Dest (sort {int($Headers{1}{$a}{"Position"})<=>int($Headers{1}{$b}{"Position"})} keys(%{$Headers{1}}))
- {
- my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
- my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
- my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
- my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
- print get_one_step_title($Header_Name.$Dest_Comment, $Header_Num, $All_Count, $Prev_Header_Length, 1)."\r";
- %TypeDescr = ();
- %FuncDescr = ();
- %ClassFunc = ();
- %ClassVirtFunc = ();
- %LibInfo = ();
- %CompleteSignature = ();
- %Cache = ();
- $Version = 1;
- parseHeader($Header_Dest);
- $Version = 2;
- my $PairHeaderDest = find_pair_header($Header_Dest);
- if(not $PairHeaderDest)
- {
- $Header_Num += 1;
- next;
- }
- parseHeader($PairHeaderDest);
- mergeSignatures();
- mergeConstants();
- $Header_Num += 1;
- $Prev_Header_Length = length($Header_Name.$Dest_Comment);
- }
- print get_one_step_title("", $All_Count, $All_Count, $Prev_Header_Length, 0)."\n";
-}
-
-sub get_one_step_title($$$$$)
-{
- my ($Header_Name, $Num, $All_Count, $SpacesAtTheEnd, $ShowCurrent) = @_;
- my ($Spaces_1, $Spaces_2, $Title) = ();
- my $Title_1 = "checking headers: $Num/$All_Count [".restrict_num_decimal_digits($Num*100/$All_Count, 3)."%]".(($ShowCurrent)?",":"");
- foreach (0 .. length("checking headers: ")+length($All_Count)*2+11 - length($Title_1))
- {
- $Spaces_1 .= " ";
- }
- $Title .= $Title_1.$Spaces_1;
- if($ShowCurrent)
- {
- my $Title_2 = "current: $Header_Name";
- foreach (0 .. $SpacesAtTheEnd - length($Header_Name)-1)
- {
- $Spaces_2 .= " ";
- }
- $Title .= $Title_2.$Spaces_2;
- }
- else
- {
- foreach (0 .. $SpacesAtTheEnd + length(" current: ") - 1)
- {
- $Title .= " ";
- }
- }
- return $Title."\r";
-}
-
-sub find_pair_header($)
-{
- my $Header_Dest = $_[0];
- my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
- my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
- my @Pair_Dest = keys(%{$HeaderName_Destinations{2}{$Header_Name}});
- if($#Pair_Dest==0)
- {
- return $Pair_Dest[0];
- }
- elsif($#Pair_Dest==-1)
- {
- return "";
- }
- else
- {
- foreach my $Pair_Dest (@Pair_Dest)
- {
- my $Pair_Identity = $Headers{2}{$Pair_Dest}{"Identity"};
- if($Identity eq $Pair_Identity)
- {
- return $Pair_Dest;
- }
- }
- return "";
- }
-}
-
-sub getSymbols($)
-{
- my $LibVersion = $_[0];
- my @SoLibPaths = getSoPaths($LibVersion);
- if($#SoLibPaths eq -1 and not $CheckHeadersOnly)
- {
- print "ERROR: shared objects were not found\n";
- exit(1);
- }
- foreach my $SoLibPath (@SoLibPaths)
- {
- getSymbols_Lib($LibVersion, $SoLibPath, 0);
- }
-}
-
-sub separatePath($)
-{
- return ("", $_[0])if($_[0] !~ /\//);
- if($_[0] =~ /\A(.*\/)([^\/]*)\Z/)
- {
- return ($1, $2);
- }
- else
- {
- return ("", $_[0]);
- }
-}
-
-sub translateSymbols($)
-{
- my $LibVersion = $_[0];
- my (@MnglNames, @UnMnglNames) = ();
- foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
- {
- if($Interface =~ /\A_Z/)
- {
- $Interface =~ s/[\@]+(.*)\Z//;
- push(@MnglNames, $Interface);
- }
- else
- {
- $tr_name{$Interface} = $Interface;
- $mangled_name{$tr_name{$Interface}} = $Interface;
- }
- }
- if($#MnglNames > -1)
- {
- @UnMnglNames = reverse(unmangleArray(@MnglNames));
- foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
- {
- if($Interface =~ /\A_Z/)
- {
- $Interface =~ s/[\@]+(.*)\Z//;
- $tr_name{$Interface} = pop(@UnMnglNames);
- $mangled_name{correctName($tr_name{$Interface})} = $Interface;
- }
- }
- }
-}
-
-sub detectAdded()
-{
- #detecting added
- foreach my $Interface (keys(%{$Interface_Library{2}}))
- {
- if(not $Interface_Library{1}{$Interface})
- {
- $AddedInt{$Interface} = 1;
- my ($MnglName, $SymbolVersion) = ($Interface, "");
- if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
- {
- ($MnglName, $SymbolVersion) = ($1, $2);
- }
- $FuncAttr{2}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
- }
- }
-}
-
-sub detectWithdrawn()
-{
- #detecting withdrawn
- foreach my $Interface (keys(%{$Interface_Library{1}}))
- {
- if(not $Interface_Library{2}{$Interface} and not $Interface_Library{2}{$SymVer{2}{$Interface}})
- {
- next if($DepInterfaces{2}{$Interface});
- $WithdrawnInt{$Interface} = 1;
- my ($MnglName, $SymbolVersion) = ($Interface, "");
- if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
- {
- ($MnglName, $SymbolVersion) = ($1, $2);
- }
- $FuncAttr{1}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
- }
- }
-}
-
-sub isRecurLib($)
-{
- my $LibName = $_[0];
- foreach my $LibNameInStack (@RecurLib)
- {
- if($LibName eq $LibNameInStack)
- {
- return 1;
- }
- }
- return 0;
-}
-
-sub getSymbols_App($)
-{
- my $Path = $_[0];
- return () if(not $Path or not -f $Path);
- my @Ints = ();
- open(APP, "readelf -WhlSsdA $Path |");
- my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
- while(<APP>)
- {
- if($symtab == 1) {
- #do nothing with symtab (but there are some plans for the future)
- next;
- }
- if( /'.dynsym'/ ) {
- $symtab=0;
- }
- elsif( /'.symtab'/ ) {
- $symtab=1;
- }
- elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
- if( $Ndx eq "UND" ) {
- #only exported interfaces
- push(@Ints, $fullname);
- }
- }
- }
- close(APP);
- return @Ints;
-}
-
-sub readlile_ELF($)
-{
- if($_[0]=~/\s*\d+:\s+(\w*)\s+\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s((\w|@|\.)+)/)
- {#the line of 'readelf' output corresponding to the interface
- my ($value, $type, $bind, $vis, $Ndx, $fullname)=($1, $2, $3, $4, $5, $6);
- if(($bind ne "WEAK") and ($bind ne "GLOBAL")) {
- return ();
- }
- if(($type ne "FUNC") and ($type ne "OBJECT") and ($type ne "COMMON")) {
- return ();
- }
- if($vis ne "DEFAULT") {
- return ();
- }
- if(($Ndx eq "ABS") and ($value !~ /\D|1|2|3|4|5|6|7|8|9/)) {
- return ();
- }
- return ($fullname, $value, $Ndx);
- }
- else
- {
- return ();
- }
-}
-
-sub getSymbols_Lib($$$)
-{
- my ($LibVersion, $Lib_Path, $IsNeededLib) = @_;
- return if(not $Lib_Path or not -f $Lib_Path);
- my ($Lib_Dir, $Lib_SoName) = separatePath($Lib_Path);
- return if($CheckedSoLib{$LibVersion}{$Lib_SoName} and $IsNeededLib);
- return if(isRecurLib($Lib_SoName) or $#RecurLib>=1);
- $CheckedSoLib{$LibVersion}{$Lib_SoName} = 1;
- push(@RecurLib, $Lib_SoName);
- my (%Value_Interface, %Interface_Value, %NeededLib) = ();
- if(not $IsNeededLib)
- {
- $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
- }
- open(SOLIB, "readelf -WhlSsdA $Lib_Path |");
- my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
- while(<SOLIB>)
- {
- if($symtab == 1) {
- #do nothing with symtab (but there are some plans for the future)
- next;
- }
- if(/'.dynsym'/) {
- $symtab=0;
- }
- elsif(/'.symtab'/) {
- $symtab=1;
- }
- elsif(/NEEDED.+\[([^\[\]]+)\]/)
- {
- $NeededLib{$1} = 1;
- }
- elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
- if( $Ndx eq "UND" ) {
- #ignore interfaces that are exported form somewhere else
- next;
- }
- my ($realname, $version) = ($fullname, "");
- if($fullname =~ /\A([^@]+)[\@]+([^@]+)\Z/)
- {
- ($realname, $version) = ($1, $2);
- }
- next if(defined $InterfacesListPath and not $InterfacesList{$realname});
- next if(defined $AppPath and not $InterfacesList_App{$realname});
- if($IsNeededLib)
- {
- $DepInterfaces{$LibVersion}{$fullname} = 1;
- }
- if(not $IsNeededLib or (defined $InterfacesListPath and $InterfacesList{$realname}) or (defined $AppPath and $InterfacesList_App{$realname}))
- {
- $Interface_Library{$LibVersion}{$fullname} = $Lib_SoName;
- $Library_Interface{$LibVersion}{$Lib_SoName}{$fullname} = 1;
- $Interface_Value{$LibVersion}{$fullname} = $idx;
- $Value_Interface{$LibVersion}{$idx}{$fullname} = 1;
- if(not $Language{$LibVersion}{$Lib_SoName})
- {
- if($fullname =~ /\A_Z[A-Z]*[0-9]+/)
- {
- $Language{$LibVersion}{$Lib_SoName} = "C++";
- }
- }
- }
- }
- }
- close(SOLIB);
- if(not $IsNeededLib)
- {
- foreach my $Interface_Name (keys(%{$Interface_Library{$LibVersion}}))
- {
- next if($Interface_Name !~ /\@/);
- my $Interface_SymName = "";
- foreach my $InterfaceName_SameValue (keys(%{$Value_Interface{$LibVersion}{$Interface_Value{$LibVersion}{$Interface_Name}}}))
- {
- if($InterfaceName_SameValue ne $Interface_Name)
- {
- $SymVer{$LibVersion}{$InterfaceName_SameValue} = $Interface_Name;
- $Interface_SymName = $InterfaceName_SameValue;
- last;
- }
- }
- if(not $Interface_SymName)
- {
- if($Interface_Name =~ /\A([^@]*)[\@]+([^@]*)\Z/ and not $SymVer{$LibVersion}{$1})
- {
- $SymVer{$LibVersion}{$1} = $Interface_Name;
- }
- }
- }
- }
- foreach my $SoLib (keys(%NeededLib))
- {
- getSymbols_Lib($LibVersion, find_solib_path($Lib_Dir, $SoLib), 1);
- }
- pop(@RecurLib);
-}
-
-sub find_solib_path($$)
-{
- my ($Dir, $SoName) = @_;
- $Dir=~s/\/\Z//g;
- if(-f $Dir."/".$SoName)
- {
- return $Dir."/".$SoName;
- }
- else
- {
- return $SoLib_DefaultPath{$SoName};
- }
-}
-
-sub symbols_Preparation($)
-{#recreate %SoNames and %Language using info from *.abi file
- my $LibVersion = $_[0];
- foreach my $Lib_SoName (keys(%{$Library_Interface{$LibVersion}}))
- {
- foreach my $Interface_Name (keys(%{$Library_Interface{$LibVersion}{$Lib_SoName}}))
- {
- $Interface_Library{$LibVersion}{$Interface_Name} = $Lib_SoName;
- $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
- if(not $Language{$LibVersion}{$Lib_SoName})
- {
- if($Interface_Name =~ /\A_Z[A-Z]*[0-9]+/)
- {
- $Language{$LibVersion}{$Lib_SoName} = "C++";
- }
- }
- }
- }
-}
-
-sub getSoPaths($)
-{
- my $LibVersion = $_[0];
- my @SoPaths = ();
- foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Libs"}))
- {
- $Dest =~ s/\A\s+|\s+\Z//g;
- next if(not $Dest);
- if(not -e $Dest)
- {
- print "ERROR: can't access \'$Dest\'\n";
- }
- my @SoPaths_Dest = getSOPaths_Dest($Dest);
- foreach (@SoPaths_Dest)
- {
- push(@SoPaths, $_);
- }
- }
- return @SoPaths;
-}
-
-sub getSOPaths_Dest($)
-{
- my $Dest = $_[0];
- if(-f $Dest)
- {
- return $Dest;
- }
- my @AllObjects = cmd_find($Dest,"f","*\.so*");
- my @SOPaths = ();
- foreach my $SharedObject (@AllObjects)
- {
- if(cmd_file($SharedObject) =~ /shared object/)
- {
- @SOPaths = (@SOPaths, $SharedObject);
- }
- }
- return @SOPaths;
-}
-
-sub genDescriptorTemplate()
-{
- writeFile("library-descriptor.xml", $Descriptor_Template."\n");
- print "descriptor template named 'library-descriptor.xml' has been generated in the current directory\n";
-}
-
-sub detectPointerSize()
-{
- `mkdir -p temp`;
- writeFile("temp/get_pointer_size.c", "#include <stdio.h>
-int main()
-{
- printf(\"\%d\", sizeof(int*));
- return 0;
-}\n");
- system("gcc temp/get_pointer_size.c -o temp/get_pointer_size");
- $POINTER_SIZE = `./temp/get_pointer_size`;
- `rm -fr temp`;
-}
-
-sub data_Preparation($)
-{
- my $LibVersion = $_[0];
- if($Descriptor{$LibVersion}{"Path"} =~ /\.abi\.tar\.gz/)
- {
- my $FileName = cmd_tar($Descriptor{$LibVersion}{"Path"});
- if($FileName =~ /\.abi/)
- {
- chomp($FileName);
- my $LibraryABI = eval readFile($FileName);
- system("rm", "-f", $FileName);
- $TypeDescr{$LibVersion} = $LibraryABI->{"TypeDescr"};
- $FuncDescr{$LibVersion} = $LibraryABI->{"FuncDescr"};
- $Library_Interface{$LibVersion} = $LibraryABI->{"Interfaces"};
- $SymVer{$LibVersion} = $LibraryABI->{"SymVer"};
- $Tid_TDid{$LibVersion} = $LibraryABI->{"Tid_TDid"};
- $Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
- $OpaqueTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
- $InternalInterfaces{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
- $Headers{$LibVersion} = $LibraryABI->{"Headers"};
- $SoNames_All{$LibVersion} = $LibraryABI->{"SharedObjects"};
- $Constants{$LibVersion} = $LibraryABI->{"Constants"};
- if($LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"} ne $ABI_COMPLIANCE_CHECKER_VERSION)
- {
- print "ERROR: incompatible version of specified ABI dump (allowed only $ABI_COMPLIANCE_CHECKER_VERSION)\n";
- exit(1);
- }
- foreach my $Destination (keys(%{$Headers{$LibVersion}}))
- {
- my $Header = get_FileName($Destination);
- $HeaderName_Destinations{$LibVersion}{$Header}{$Destination} = 1;
- }
- symbols_Preparation($LibVersion);
- }
- }
- elsif($Descriptor{$LibVersion}{"Path"} =~ /\.tar\.gz\Z/)
- {
- print "ERROR: descriptor must be an XML file or '*.abi.tar.gz' ABI dump\n";
- exit(1);
- }
- else
- {
- readDescriptor($LibVersion);
- if(not $CheckHeadersOnly)
- {
- getSymbols($LibVersion);
- }
- headerSearch($LibVersion);
- }
-}
-
-sub dump_sorting($)
-{
- my $hash = $_[0];
- if((keys(%{$hash}))[0] =~ /\A[0-9]+\Z/)
- {
- return [sort {int($a) <=> int($b)} keys %{$hash}];
- }
- else
- {
- return [sort {$a cmp $b} keys %{$hash}];
- }
-}
-
-sub get_solib_default_paths()
-{
- foreach my $Line (split("\n", `ldconfig -p`))
- {
- if($Line=~/\A[ \t]*([^ \t]+) .* \=\> (.+)\Z/)
- {
- $SoLib_DefaultPath{$1} = $2;
- }
- }
-}
-
-sub scenario()
-{
- if(defined $Help)
- {
- HELP_MESSAGE();
- exit(0);
- }
- if(defined $ShowVersion)
- {
- 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";
- exit(0);
- }
- $Data::Dumper::Sortkeys = \&dump_sorting;
- if(defined $TestSystem)
- {
- testSystem_cpp();
- testSystem_c();
- exit(0);
- }
- if($GenerateDescriptor)
- {
- genDescriptorTemplate();
- exit(0);
- }
- if(not defined $TargetLibraryName)
- {
- print "select library name (option -l <name>)\n";
- exit(1);
- }
- if(defined $InterfacesListPath)
- {
- if(not -f $InterfacesListPath)
- {
- print "ERROR: can't access file $InterfacesListPath\n";
- exit(1);
- }
- foreach my $Interface (split("\n", readFile($InterfacesListPath)))
- {
- $InterfacesList{$Interface} = 1;
- }
- }
- if($AppPath)
- {
- if(-f $AppPath)
- {
- foreach my $Interface (getSymbols_App($AppPath))
- {
- $InterfacesList_App{$Interface} = 1;
- }
- }
- else
- {
- print "ERROR: can't access file \'$AppPath\'\n";
- exit(1);
- }
- }
- get_solib_default_paths();
- if($DumpInfo_DescriptorPath)
- {
- if(not -f $DumpInfo_DescriptorPath)
- {
- print "ERROR: can't access file \'$DumpInfo_DescriptorPath\'\n";
- exit(1);
- }
- $Descriptor{1}{"Path"} = $DumpInfo_DescriptorPath;
- readDescriptor(1);
- detectPointerSize();
- getSymbols(1);
- translateSymbols(1);
- headerSearch(1);
- parseHeaders_AllInOne(1);
- cleanData(1);
- my %LibraryABI = ();
- print "creating library ABI info dump ...\n";
- $LibraryABI{"TypeDescr"} = $TypeDescr{1};
- $LibraryABI{"FuncDescr"} = $FuncDescr{1};
- $LibraryABI{"Interfaces"} = $Library_Interface{1};
- $LibraryABI{"SymVer"} = $SymVer{1};
- $LibraryABI{"LibraryVersion"} = $Descriptor{1}{"Version"};
- $LibraryABI{"Library"} = $TargetLibraryName;
- $LibraryABI{"SharedObjects"} = $SoNames_All{1};
- $LibraryABI{"Tid_TDid"} = $Tid_TDid{1};
- $LibraryABI{"OpaqueTypes"} = $OpaqueTypes{1};
- $LibraryABI{"InternalInterfaces"} = $InternalInterfaces{1};
- $LibraryABI{"Headers"} = $Headers{1};
- $LibraryABI{"Constants"} = $Constants{1};
- $LibraryABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $ABI_COMPLIANCE_CHECKER_VERSION;
- my $InfoDump_FilePath = "abi_dumps/$TargetLibraryName";
- my $InfoDump_FileName = $TargetLibraryName."_".$Descriptor{1}{"Version"}.".abi";
- system("mkdir", "-p", $InfoDump_FilePath);
- system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName.".tar.gz");
- writeFile("$InfoDump_FilePath/$InfoDump_FileName", Dumper(\%LibraryABI));
- system("cd ".esc($InfoDump_FilePath)." && tar -cf ".esc($InfoDump_FileName).".tar ".esc($InfoDump_FileName));
- system("cd ".esc($InfoDump_FilePath)." && gzip ".esc($InfoDump_FileName).".tar --best");
- system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName);
- if($?)
- {
- print "ERROR: can't create library ABI info dump\n";
- exit(1);
- }
- else
- {
- print "see library ABI info dump in \'$InfoDump_FilePath/$InfoDump_FileName\.tar\.gz\': use it instead of library version descriptor on other machine\n";
- exit(0);
- }
- }
- if(not $Descriptor{1}{"Path"})
- {
- print "select 1st library descriptor (option -d1 <path>)\n";
- exit(1);
- }
- if(not -f $Descriptor{1}{"Path"})
- {
- print "ERROR: descriptor d1 does not exist, incorrect file path '".$Descriptor{1}{"Path"}."'\n";
- exit(1);
- }
- if(not $Descriptor{2}{"Path"})
- {
- print "select 2nd library descriptor (option -d2 <path>)\n";
- exit(1);
- }
- if(not -f $Descriptor{2}{"Path"})
- {
- print "ERROR: descriptor d2 does not exist, incorrect file path '".$Descriptor{2}{"Path"}."'\n";
- exit(1);
- }
- $StartTime = localtime time;
- print "preparation...\n";
- data_Preparation(1);
- data_Preparation(2);
- if($AppPath and not keys(%{$Interface_Library{1}}))
- {
- print "WARNING: symbols from the specified application were not found in the specified library shared objects\n";
- }
- $REPORT_PATH = "compat_reports/$TargetLibraryName/".$Descriptor{1}{"Version"}."_to_".$Descriptor{2}{"Version"};
- system("mkdir", "-p", $REPORT_PATH);
- system("rm", "-f", $REPORT_PATH."/abi_compat_report.html");
- detectPointerSize();
- translateSymbols(1);
- translateSymbols(2);
- if(not $CheckHeadersOnly)
- {
- detectAdded();
- detectWithdrawn();
- }
- #headers merging
- if($HeaderCheckingMode_Separately and $Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/ and $Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
- {
- mergeHeaders_Separately();
- }
- else
- {
- if($Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/)
- {
- parseHeaders_AllInOne(1);
- }
- if($Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
- {
- parseHeaders_AllInOne(2);
- }
- print "comparing headers ...\n";
- mergeSignatures();
- mergeConstants();
- }
- #libraries merging
- if(not $CheckHeadersOnly)
- {
- print "comparing shared objects ...\n";
- mergeLibs();
- }
- print "creating ABI compliance report ...\n";
- create_HtmlReport();
- if($HeaderCheckingMode_Separately)
- {
- if(keys(%HeaderCompileError))
- {
- print "\nWARNING: compilation errors in following headers:\n";
- foreach my $Header (keys(%HeaderCompileError))
- {
- print $Header." ";
- }
- print "\nyou can see compilation errors in the following files:\n '$ERR_PATH{1}'\n '$ERR_PATH{2}'\n";
- }
- }
- `rm -fr temp`;
- print "\nstarted: $StartTime, finished: ".(localtime time)."\n" if($ShowExpendTime);
- print "see the ABI compliance report in the file '$REPORT_PATH/abi_compat_report.html'\n";
- exit(0);
-}
-
-scenario();
diff --git a/abicheck/run_abi_test b/abicheck/run_abi_test
index 4e4bdf298..9ee840ea0 100755
--- a/abicheck/run_abi_test
+++ b/abicheck/run_abi_test
@@ -5,10 +5,15 @@ if [ ! -d ../build ]; then
exit 1
fi
+if [ ! -x "$(which abi-compliance-checker 2>/dev/null )" ]; then
+ echo "Please install the 'abi-compliance-checker' package"
+ exit 1
+fi
+
LIBPATH=$(find /usr/lib/ -type f -name "libapt-*.so.*" -printf %p\\\\n)
sed s#@installed_libapt@#$LIBPATH# apt_installed.xml.in > apt_installed.xml
BUILDPATH=$(readlink -f ../build)
sed s#@build_path@#$BUILDPATH# apt_build.xml.in > apt_build.xml
-perl abi-compliance-checker.pl -l apt -d1 apt_installed.xml -d2 apt_build.xml
+abi-compliance-checker -l apt -d1 apt_installed.xml -d2 apt_build.xml
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index f70cabeff..97b2d1e29 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -1069,8 +1069,7 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
string Final = _config->FindDir("Dir::State::lists");
Final += URItoFileName(RealURI);
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) == 0)
+ if (RealFileExists(Final) == true)
{
// File was already in place. It needs to be re-downloaded/verified
// because Release might have changed, we do give it a differnt
@@ -1084,6 +1083,19 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
QueueURI(Desc);
}
/*}}}*/
+pkgAcqMetaSig::~pkgAcqMetaSig() /*{{{*/
+{
+ // if the file was never queued undo file-changes done in the constructor
+ if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false &&
+ LastGoodSig.empty() == false)
+ {
+ string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
+ Rename(LastGoodSig, Final);
+ }
+
+}
+ /*}}}*/
// pkgAcqMetaSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
/* The only header we use is the last-modified header. */
@@ -1597,14 +1609,25 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/
// keep the old InRelease around in case of transistent network errors
string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) == 0)
+ if (RealFileExists(Final) == true)
{
string const LastGoodSig = DestFile + ".reverify";
Rename(Final,LastGoodSig);
}
}
/*}}}*/
+pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/
+{
+ // if the file was never queued undo file-changes done in the constructor
+ if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false)
+ {
+ string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ string const LastGoodSig = DestFile + ".reverify";
+ if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
+ Rename(LastGoodSig, Final);
+ }
+}
+ /*}}}*/
// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
// FIXME: this can go away once the InRelease file is used widely
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 51d539450..10c855e63 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -774,6 +774,7 @@ class pkgAcqMetaSig : public pkgAcquire::Item
std::string MetaIndexURI, std::string MetaIndexURIDesc, std::string MetaIndexShortDesc,
const std::vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
+ virtual ~pkgAcqMetaSig();
};
/*}}}*/
/** \brief An item that is responsible for downloading the meta-index {{{
@@ -904,6 +905,7 @@ public:
std::string const &MetaSigURI, std::string const &MetaSigURIDesc, std::string const &MetaSigShortDesc,
const std::vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
+ virtual ~pkgAcqMetaClearSig();
};
/*}}}*/
/** \brief An item that is responsible for fetching a package file. {{{
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 85799a11b..69d4acd83 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -459,6 +459,49 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
return Fix.ResolveByKeep();
}
/*}}}*/
+// AllUpgradeNoDelete - Upgrade without removing packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ * Upgrade as much as possible without deleting anything (useful for
+ * stable systems)
+ */
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache)
+{
+ pkgDepCache::ActionGroup group(Cache);
+
+ pkgProblemResolver Fix(&Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // provide the initial set of stuff we want to upgrade by marking
+ // all upgradable packages for upgrade
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ {
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ Cache.MarkInstall(I, false, 0, false);
+ }
+ }
+
+ // then let auto-install loose
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Install())
+ Cache.MarkInstall(I, true, 0, false);
+
+ // ... but it may remove stuff, we we need to clean up afterwards again
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Delete() == true)
+ Cache.MarkKeep(I, false, false);
+
+ // resolve remaining issues via keep
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
// ---------------------------------------------------------------------
/* This simply goes over the entire set of packages and tries to keep
@@ -550,14 +593,12 @@ void pkgProblemResolver::MakeScores()
unsigned long Size = Cache.Head().PackageCount;
memset(Scores,0,sizeof(*Scores)*Size);
- // Maps to pkgCache::State::VerPriority
- // which is "Important Required Standard Optional Extra"
- // (yes, that is confusing, the order of pkgCache::State::VerPriority
- // needs to be adjusted but that requires a ABI break)
+ // maps to pkgCache::State::VerPriority:
+ // Required Important Standard Optional Extra
int PrioMap[] = {
0,
- _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Required",3),
+ _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Standard",1),
_config->FindI("pkgProblemResolver::Scores::Optional",-1),
_config->FindI("pkgProblemResolver::Scores::Extra",-2)
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index 7f58c8eed..a499db8ba 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -143,7 +143,11 @@ class pkgProblemResolver /*{{{*/
bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
+
bool pkgAllUpgrade(pkgDepCache &Cache);
+
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache);
+
bool pkgMinimizeUpgrade(pkgDepCache &Cache);
void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List);
diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc
index 64cde41d1..57b9af159 100644
--- a/apt-pkg/cachefilter.cc
+++ b/apt-pkg/cachefilter.cc
@@ -55,6 +55,17 @@ PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/
}
/*}}}*/
+// Fnmatch support /*{{{*/
+//----------------------------------------------------------------------
+bool PackageNameMatchesFnmatch::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Pkg.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+bool PackageNameMatchesFnmatch::operator() (pkgCache::GrpIterator const &Grp) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Grp.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+
// CompleteArch to <kernel>-<cpu> tuple /*{{{*/
//----------------------------------------------------------------------
/* The complete architecture, consisting of <kernel>-<cpu>. */
diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h
index 25cd43f47..34b7d0b46 100644
--- a/apt-pkg/cachefilter.h
+++ b/apt-pkg/cachefilter.h
@@ -14,6 +14,10 @@
/*}}}*/
namespace APT {
namespace CacheFilter {
+
+#define PACKAGE_MATCHER_ABI_COMPAT 1
+#ifdef PACKAGE_MATCHER_ABI_COMPAT
+
// PackageNameMatchesRegEx /*{{{*/
class PackageNameMatchesRegEx {
/** \brief dpointer placeholder (for later in case we need it) */
@@ -26,6 +30,19 @@ public:
~PackageNameMatchesRegEx();
};
/*}}}*/
+// PackageNameMatchesFnmatch /*{{{*/
+ class PackageNameMatchesFnmatch {
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ const std::string Pattern;
+public:
+ PackageNameMatchesFnmatch(std::string const &Pattern)
+ : Pattern(Pattern) {};
+ bool operator() (pkgCache::PkgIterator const &Pkg);
+ bool operator() (pkgCache::GrpIterator const &Grp);
+ ~PackageNameMatchesFnmatch() {};
+};
+ /*}}}*/
// PackageArchitectureMatchesSpecification /*{{{*/
/** \class PackageArchitectureMatchesSpecification
\brief matching against architecture specification strings
@@ -55,6 +72,73 @@ public:
bool operator() (pkgCache::VerIterator const &Ver);
~PackageArchitectureMatchesSpecification();
};
+
+#else
+
+class PackageMatcher {
+ public:
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg) { return false; };
+ virtual bool operator() (pkgCache::GrpIterator const &Grp) { return false; };
+ virtual bool operator() (pkgCache::VerIterator const &Ver) { return false; };
+
+ virtual ~PackageMatcher() {};
+};
+
+// PackageNameMatchesRegEx /*{{{*/
+class PackageNameMatchesRegEx : public PackageMatcher {
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ regex_t* pattern;
+public:
+ PackageNameMatchesRegEx(std::string const &Pattern);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
+ virtual ~PackageNameMatchesRegEx();
+};
+ /*}}}*/
+// PackageNameMatchesFnmatch /*{{{*/
+ class PackageNameMatchesFnmatch : public PackageMatcher{
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ const std::string Pattern;
+public:
+ PackageNameMatchesFnmatch(std::string const &Pattern)
+ : Pattern(Pattern) {};
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
+ virtual ~PackageNameMatchesFnmatch() {};
+};
+ /*}}}*/
+// PackageArchitectureMatchesSpecification /*{{{*/
+/** \class PackageArchitectureMatchesSpecification
+ \brief matching against architecture specification strings
+
+ The strings are of the format <kernel>-<cpu> where either component,
+ or the whole string, can be the wildcard "any" as defined in
+ debian-policy §11.1 "Architecture specification strings".
+
+ Examples: i386, mipsel, linux-any, any-amd64, any */
+class PackageArchitectureMatchesSpecification : public PackageMatcher {
+ std::string literal;
+ std::string complete;
+ bool isPattern;
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+public:
+ /** \brief matching against architecture specification strings
+ *
+ * @param pattern is the architecture specification string
+ * @param isPattern defines if the given \b pattern is a
+ * architecture specification pattern to match others against
+ * or if it is the fixed string and matched against patterns
+ */
+ PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern = true);
+ bool operator() (char const * const &arch);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::VerIterator const &Ver);
+ virtual ~PackageArchitectureMatchesSpecification();
+};
+#endif
/*}}}*/
}
}
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index 1fea4f94a..0147f7e86 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -155,6 +155,69 @@ bool PackageContainerInterface::FromRegEx(PackageContainerInterface * const pci,
return true;
}
/*}}}*/
+// FromFnmatch - Returns the package defined by this fnmatch /*{{{*/
+bool
+PackageContainerInterface::FromFnmatch(PackageContainerInterface * const pci,
+ pkgCacheFile &Cache,
+ std::string pattern,
+ CacheSetHelper &helper)
+{
+ static const char * const isfnmatch = ".?*[]!";
+ if (pattern.find_first_of(isfnmatch) == std::string::npos)
+ return false;
+
+ bool const wasEmpty = pci->empty();
+ if (wasEmpty == true)
+ pci->setConstructor(FNMATCH);
+
+ size_t archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ if (arch.find_first_of(isfnmatch) == std::string::npos)
+ pattern.erase(archfound);
+ else
+ arch = "native";
+ }
+
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return false;
+
+ APT::CacheFilter::PackageNameMatchesFnmatch filter(pattern);
+
+ bool found = false;
+ for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) {
+ if (filter(Grp) == false)
+ continue;
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true) {
+ if (archfound == std::string::npos) {
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end() && Pkg.end() != true; ++a)
+ Pkg = Grp.FindPkg(*a);
+ }
+ if (Pkg.end() == true)
+ continue;
+ }
+
+ pci->insert(Pkg);
+ helper.showRegExSelection(Pkg, pattern);
+ found = true;
+ }
+
+ if (found == false) {
+ helper.canNotFindRegEx(pci, Cache, pattern);
+ pci->setConstructor(UNKNOWN);
+ return false;
+ }
+
+ if (wasEmpty == false && pci->getConstructor() != UNKNOWN)
+ pci->setConstructor(UNKNOWN);
+
+ return true;
+}
+ /*}}}*/
// FromName - Returns the package defined by this string /*{{{*/
pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache,
std::string const &str, CacheSetHelper &helper) {
@@ -239,6 +302,7 @@ bool PackageContainerInterface::FromString(PackageContainerInterface * const pci
if (FromGroup(pci, Cache, str, helper) == false &&
FromTask(pci, Cache, str, helper) == false &&
+ FromFnmatch(pci, Cache, str, helper) == false &&
FromRegEx(pci, Cache, str, helper) == false)
{
helper.canNotFindPackage(pci, Cache, str);
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index d7328d705..29103aad9 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -131,13 +131,14 @@ public:
virtual bool empty() const = 0;
virtual void clear() = 0;
- enum Constructor { UNKNOWN, REGEX, TASK };
+ enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
virtual void setConstructor(Constructor const &con) = 0;
virtual Constructor getConstructor() const = 0;
static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+ static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
@@ -259,6 +260,16 @@ public: /*{{{*/
return FromRegEx(Cache, pattern, helper);
}
+ static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ PackageContainer cont(FNMATCH);
+ PackageContainerInterface::FromFnmatch(&cont, Cache, pattern, helper);
+ return cont;
+ }
+ static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return FromFnmatch(Cache, pattern, helper);
+ }
+
/** \brief returns a package specified by a string
\param Cache the package is in
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index d77ef4540..2086d91ca 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -38,6 +38,42 @@ CommandLine::~CommandLine()
delete [] FileList;
}
/*}}}*/
+// CommandLine::GetCommand - return the first non-option word /*{{{*/
+char const * CommandLine::GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv)
+{
+ // if there is a -- on the line there must be the word we search for around it
+ // as -- marks the end of the options, just not sure if the command can be
+ // considered an option or not, so accept both
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (strcmp(argv[i], "--") != 0)
+ continue;
+ ++i;
+ if (i < argc)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ i -= 2;
+ if (i != 0)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ return NULL;
+ }
+ // no --, so search for the first word matching a command
+ // FIXME: How like is it that an option parameter will be also a valid Match ?
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (*(argv[i]) == '-')
+ continue;
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ }
+ return NULL;
+}
+ /*}}}*/
// CommandLine::Parse - Main action member /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -391,3 +427,15 @@ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * co
_config->Set("CommandLine::AsString", cmdline);
}
/*}}}*/
+CommandLine::Args CommandLine::MakeArgs(char ShortOpt, char const *LongOpt, char const *ConfName, unsigned long Flags)/*{{{*/
+{
+ /* In theory, this should be a constructor for CommandLine::Args instead,
+ but this breaks compatibility as gcc thinks this is a c++11 initializer_list */
+ CommandLine::Args arg;
+ arg.ShortOpt = ShortOpt;
+ arg.LongOpt = LongOpt;
+ arg.ConfName = ConfName;
+ arg.Flags = Flags;
+ return arg;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h
index 9f505fd41..180276633 100644
--- a/apt-pkg/contrib/cmndline.h
+++ b/apt-pkg/contrib/cmndline.h
@@ -83,6 +83,12 @@ class CommandLine
unsigned int FileSize() const;
bool DispatchArg(Dispatch *List,bool NoMatch = true);
+ static char const * GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv);
+
+ static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt,
+ char const *ConfName, unsigned long Flags);
+
CommandLine(Args *AList,Configuration *Conf);
~CommandLine();
};
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 376617401..4ef4663c0 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -422,6 +422,18 @@ void Configuration::Clear(string const &Name, string const &Value)
}
/*}}}*/
+// Configuration::Clear - Clear everything /*{{{*/
+// ---------------------------------------------------------------------
+void Configuration::Clear()
+{
+ const Configuration::Item *Top = Tree(0);
+ while( Top != 0 )
+ {
+ Clear(Top->FullTag());
+ Top = Top->Next;
+ }
+}
+ /*}}}*/
// Configuration::Clear - Clear an entire tree /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index ea94c2fe6..8e09ea0a6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -94,6 +94,7 @@ class Configuration
// clear a whole tree
void Clear(const std::string &Name);
+ void Clear();
// remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
void Clear(std::string const &List, std::string const &Value);
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index f24df65fc..dca468c63 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -41,6 +41,8 @@
#include <dirent.h>
#include <signal.h>
#include <errno.h>
+#include <glob.h>
+
#include <set>
#include <algorithm>
@@ -1766,3 +1768,32 @@ bool FileFd::FileFdError(const char *Description,...) {
/*}}}*/
gzFile FileFd::gzFd() { return (gzFile) d->gz; }
+
+
+// Glob - wrapper around "glob()" /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+std::vector<std::string> Glob(std::string const &pattern, int flags)
+{
+ std::vector<std::string> result;
+ glob_t globbuf;
+ int glob_res, i;
+
+ glob_res = glob(pattern.c_str(), flags, NULL, &globbuf);
+
+ if (glob_res != 0)
+ {
+ if(glob_res != GLOB_NOMATCH) {
+ _error->Errno("glob", "Problem with glob");
+ return result;
+ }
+ }
+
+ // append results
+ for(i=0;i<globbuf.gl_pathc;i++)
+ result.push_back(string(globbuf.gl_pathv[i]));
+
+ globfree(&globbuf);
+ return result;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 3ec01dd9a..decd64d9d 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -191,4 +191,7 @@ std::string flNoLink(std::string File);
std::string flExtension(std::string File);
std::string flCombine(std::string Dir,std::string File);
+// simple c++ glob
+std::vector<std::string> Glob(std::string const &pattern, int flags=0);
+
#endif
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index b70a62a47..0955b69f7 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -1293,6 +1293,18 @@ bool CheckDomainList(const string &Host,const string &List)
return false;
}
/*}}}*/
+// strv_length - Return the length of a NULL-terminated string array /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+size_t strv_length(const char **str_array)
+{
+ size_t i;
+ for (i=0; str_array[i] != NULL; i++)
+ /* nothing */
+ ;
+ return i;
+}
+
// DeEscapeString - unescape (\0XX and \xXX) from a string /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index e92f91dc0..530896141 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -108,6 +108,10 @@ inline int stringcasecmp(std::string::const_iterator A,std::string::const_iterat
APT_MKSTRCMP2(stringcmp,stringcmp);
APT_MKSTRCMP2(stringcasecmp,stringcasecmp);
+// Return the length of a NULL-terminated string array
+size_t strv_length(const char **str_array);
+
+
inline const char *DeNull(const char *s) {return (s == 0?"(null)":s);};
class URI
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 28857176b..87aab6ee2 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -805,94 +805,28 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
map_ptrloc const storage = WriteUniqString(component);
FileI->Component = storage;
- // FIXME: should use FileFd and TagSection
- FILE* release = fdopen(dup(File.Fd()), "r");
- if (release == NULL)
+ pkgTagFile TagFile(&File, File.Size());
+ pkgTagSection Section;
+ if (_error->PendingError() == true || TagFile.Step(Section) == false)
return false;
- char buffer[101];
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- size_t len = 0;
-
- // Skip empty lines
- for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len)
- /* nothing */
- ;
- if (buffer[len] == '\0')
- continue;
-
- // seperate the tag from the data
- const char* dataStart = strchr(buffer + len, ':');
- if (dataStart == NULL)
- continue;
- len = dataStart - buffer;
- for (++dataStart; *dataStart == ' '; ++dataStart)
- /* nothing */
- ;
- const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
- // The last char should be a newline, but we can never be sure: #633350
- const char* lineEnd = dataEnd;
- for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
- /* nothing */
- ;
- ++lineEnd;
-
- // which datastorage need to be updated
- enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
- if (buffer[0] == ' ')
- ;
- #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
- APT_PARSER_WRITETO(Suite)
- APT_PARSER_WRITETO(Component)
- APT_PARSER_WRITETO(Version)
- APT_PARSER_WRITETO(Origin)
- APT_PARSER_WRITETO(Codename)
- APT_PARSER_WRITETO(Label)
- #undef APT_PARSER_WRITETO
- #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
- pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
- APT_PARSER_FLAGIT(NotAutomatic)
- APT_PARSER_FLAGIT(ButAutomaticUpgrades)
- #undef APT_PARSER_FLAGIT
-
- // load all data from the line and save it
- string data;
- if (writeTo != None)
- data.append(dataStart, dataEnd);
- if (sizeof(buffer) - 1 == (dataEnd - buffer))
- {
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- if (writeTo != None)
- data.append(buffer);
- if (strlen(buffer) != sizeof(buffer) - 1)
- break;
- }
- }
- if (writeTo != None)
- {
- // remove spaces and stuff from the end of the data line
- for (std::string::reverse_iterator s = data.rbegin();
- s != data.rend(); ++s)
- {
- if (*s != '\r' && *s != '\n' && *s != ' ')
- break;
- *s = '\0';
- }
- map_ptrloc const storage = WriteUniqString(data);
- switch (writeTo) {
- case Suite: FileI->Archive = storage; break;
- case Component: FileI->Component = storage; break;
- case Version: FileI->Version = storage; break;
- case Origin: FileI->Origin = storage; break;
- case Codename: FileI->Codename = storage; break;
- case Label: FileI->Label = storage; break;
- case None: break;
- }
- }
+ std::string data;
+ #define APT_INRELEASE(TAG, STORE) \
+ data = Section.FindS(TAG); \
+ if (data.empty() == false) \
+ { \
+ map_ptrloc const storage = WriteUniqString(data); \
+ STORE = storage; \
}
- fclose(release);
+ APT_INRELEASE("Suite", FileI->Archive)
+ APT_INRELEASE("Component", FileI->Component)
+ APT_INRELEASE("Version", FileI->Version)
+ APT_INRELEASE("Origin", FileI->Origin)
+ APT_INRELEASE("Codename", FileI->Codename)
+ APT_INRELEASE("Label", FileI->Label)
+ #undef APT_INRELEASE
+ Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
+ Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
return !_error->PendingError();
}
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index b0bd6b184..4b5467eff 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -134,7 +134,8 @@ static void dpkgChrootDirectory()
std::cerr << "Chrooting into " << chrootDir << std::endl;
if (chroot(chrootDir.c_str()) != 0)
_exit(100);
- chdir("/");
+ if (chdir("/") != 0)
+ _exit(100);
}
/*}}}*/
@@ -381,24 +382,32 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
OptSec = "DPkg::Tools::Options::" + string(Opts->Value.c_str(),Pos);
unsigned int Version = _config->FindI(OptSec+"::Version",1);
+ unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
// Create the pipes
int Pipes[2];
if (pipe(Pipes) != 0)
return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
- SetCloseExec(Pipes[0],true);
+ if (InfoFD != (unsigned)Pipes[0])
+ SetCloseExec(Pipes[0],true);
+ else
+ _config->Set("APT::Keep-Fds::", Pipes[0]);
SetCloseExec(Pipes[1],true);
-
+
// Purified Fork for running the script
- pid_t Process = ExecFork();
+ pid_t Process = ExecFork();
if (Process == 0)
{
// Setup the FDs
- dup2(Pipes[0],STDIN_FILENO);
+ dup2(Pipes[0], InfoFD);
SetCloseExec(STDOUT_FILENO,false);
- SetCloseExec(STDIN_FILENO,false);
+ SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
+ string hookfd;
+ strprintf(hookfd, "%d", InfoFD);
+ setenv("APT_HOOK_INFO_FD", hookfd.c_str(), 1);
+
dpkgChrootDirectory();
const char *Args[4];
Args[0] = "/bin/sh";
@@ -408,6 +417,8 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
execv(Args[0],(char **)Args);
_exit(100);
}
+ if (InfoFD == (unsigned)Pipes[0])
+ _config->Clear("APT::Keep-Fds", Pipes[0]);
close(Pipes[0]);
FILE *F = fdopen(Pipes[1],"w");
if (F == 0)
@@ -750,13 +761,15 @@ bool pkgDPkgPM::OpenLog()
return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
setvbuf(d->term_out, NULL, _IONBF, 0);
SetCloseExec(fileno(d->term_out), true);
- struct passwd *pw;
- struct group *gr;
- pw = getpwnam("root");
- gr = getgrnam("adm");
- if (pw != NULL && gr != NULL)
- chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
- chmod(logfile_name.c_str(), 0640);
+ if (getuid() == 0) // if we aren't root, we can't chown a file, so don't try it
+ {
+ struct passwd *pw = getpwnam("root");
+ struct group *gr = getgrnam("adm");
+ if (pw != NULL && gr != NULL && chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid) != 0)
+ _error->WarningE("OpenLog", "chown to root:adm of file %s failed", logfile_name.c_str());
+ }
+ if (chmod(logfile_name.c_str(), 0640) != 0)
+ _error->WarningE("OpenLog", "chmod 0640 of file %s failed", logfile_name.c_str());
fprintf(d->term_out, "\nLog started: %s\n", timestr);
}
@@ -1235,16 +1248,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// if tcgetattr does not return zero there was a error
// and we do not do any pty magic
- if (tcgetattr(0, &tt) == 0)
+ _error->PushToStack();
+ if (tcgetattr(STDOUT_FILENO, &tt) == 0)
{
ioctl(0, TIOCGWINSZ, (char *)&win);
- if (openpty(&master, &slave, NULL, &tt, &win) < 0)
+ if (openpty(&master, &slave, NULL, &tt, &win) < 0)
{
- const char *s = _("Can not write log, openpty() "
- "failed (/dev/pts not mounted?)\n");
- fprintf(stderr, "%s",s);
- if(d->term_out)
- fprintf(d->term_out, "%s",s);
+ _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
master = slave = -1;
} else {
struct termios rtt;
@@ -1262,6 +1272,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigprocmask(SIG_SETMASK, &original_sigmask, 0);
}
}
+ // complain only if stdout is either a terminal (but still failed) or is an invalid
+ // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
+ else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
+ _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
+
+ if (_error->PendingError() == true)
+ _error->DumpErrors(std::cerr);
+ _error->RevertToStack();
+
// Fork dpkg
pid_t Child;
_config->Set("APT::Keep-Fds::",fd[1]);
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index e37a78cfb..8a72ca151 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -62,7 +62,7 @@ bool indexRecords::Load(const string Filename) /*{{{*/
if (OpenMaybeClearSignedFile(Filename, Fd) == false)
return false;
- pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
+ pkgTagFile TagFile(&Fd, Fd.Size());
if (_error->PendingError() == true)
{
strprintf(ErrorText, _("Unable to parse Release file %s"),Filename.c_str());
@@ -71,16 +71,11 @@ bool indexRecords::Load(const string Filename) /*{{{*/
pkgTagSection Section;
const char *Start, *End;
- // Skip over sections beginning with ----- as this is an idicator for clearsigns
- do {
- if (TagFile.Step(Section) == false)
- {
- strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
- return false;
- }
-
- Section.Get (Start, End, 0);
- } while (End - Start > 5 && strncmp(Start, "-----", 5) == 0);
+ if (TagFile.Step(Section) == false)
+ {
+ strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
+ return false;
+ }
Suite = Section.FindS("Suite");
Dist = Section.FindS("Codename");
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 4ae3b5f87..0a06cc6e3 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -166,11 +166,15 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
tracks the default when the default is taken away, and a permanent
pin that stays at that setting.
*/
+ bool PrefSeen = false;
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
{
/* Lets see if this version is the installed version */
bool instVer = (Pkg.CurrentVer() == Ver);
+ if (Pref == Ver)
+ PrefSeen = true;
+
for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; ++VF)
{
/* If this is the status file, and the current version is not the
@@ -187,26 +191,33 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
{
Pref = Ver;
Max = Prio;
+ PrefSeen = true;
}
if (Prio > MaxAlt)
{
PrefAlt = Ver;
MaxAlt = Prio;
- }
- }
-
+ }
+ }
+
if (instVer == true && Max < 1000)
{
+ /* Not having seen the Pref yet means we have a specific pin below 1000
+ on a version below the current installed one, so ignore the specific pin
+ as this would be a downgrade otherwise */
+ if (PrefSeen == false || Pref.end() == true)
+ {
+ Pref = Ver;
+ PrefSeen = true;
+ }
/* Elevate our current selection (or the status file itself)
to the Pseudo-status priority. */
- if (Pref.end() == true)
- Pref = Ver;
Max = 1000;
-
+
// Fast path optimize.
if (StatusOverride == false)
break;
- }
+ }
}
// If we do not find our candidate, use the one with the highest pin.
// This means that if there is a version available with pin > 0; there
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 83c1a9a55..868adf3d2 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -50,21 +50,27 @@ public:
/* */
pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size)
{
+ /* The size is increased by 4 because if we start with the Size of the
+ filename we need to try to read 1 char more to see an EOF faster, 1
+ char the end-pointer can be on and maybe 2 newlines need to be added
+ to the end of the file -> 4 extra chars */
+ Size += 4;
d = new pkgTagFilePrivate(pFd, Size);
if (d->Fd.IsOpen() == false)
- {
d->Start = d->End = d->Buffer = 0;
+ else
+ d->Buffer = (char*)malloc(sizeof(char) * Size);
+
+ if (d->Buffer == NULL)
d->Done = true;
- d->iOffset = 0;
- return;
- }
-
- d->Buffer = new char[Size];
+ else
+ d->Done = false;
+
d->Start = d->End = d->Buffer;
- d->Done = false;
d->iOffset = 0;
- Fill();
+ if (d->Done == false)
+ Fill();
}
/*}}}*/
// TagFile::~pkgTagFile - Destructor /*{{{*/
@@ -72,11 +78,11 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size)
/* */
pkgTagFile::~pkgTagFile()
{
- delete [] d->Buffer;
+ free(d->Buffer);
delete d;
}
/*}}}*/
-// TagFile::Offset - Return the current offset in the buffer /*{{{*/
+// TagFile::Offset - Return the current offset in the buffer /*{{{*/
unsigned long pkgTagFile::Offset()
{
return d->iOffset;
@@ -89,19 +95,22 @@ unsigned long pkgTagFile::Offset()
*/
bool pkgTagFile::Resize()
{
- char *tmp;
- unsigned long long EndSize = d->End - d->Start;
-
// fail is the buffer grows too big
if(d->Size > 1024*1024+1)
return false;
+ return Resize(d->Size * 2);
+}
+bool pkgTagFile::Resize(unsigned long long const newSize)
+{
+ unsigned long long const EndSize = d->End - d->Start;
+
// get new buffer and use it
- tmp = new char[2*d->Size];
- memcpy(tmp, d->Buffer, d->Size);
- d->Size = d->Size*2;
- delete [] d->Buffer;
- d->Buffer = tmp;
+ char* newBuffer = (char*)realloc(d->Buffer, sizeof(char) * newSize);
+ if (newBuffer == NULL)
+ return false;
+ d->Buffer = newBuffer;
+ d->Size = newSize;
// update the start/end pointers to the new buffer
d->Start = d->Buffer;
@@ -152,9 +161,10 @@ bool pkgTagFile::Fill()
if (d->Done == false)
{
// See if only a bit of the file is left
- if (d->Fd.Read(d->End, d->Size - (d->End - d->Buffer),&Actual) == false)
+ unsigned long long const dataSize = d->Size - ((d->End - d->Buffer) + 1);
+ if (d->Fd.Read(d->End, dataSize, &Actual) == false)
return false;
- if (Actual != d->Size - (d->End - d->Buffer))
+ if (Actual != dataSize || d->Fd.Eof() == true)
d->Done = true;
d->End += Actual;
}
@@ -171,8 +181,13 @@ bool pkgTagFile::Fill()
for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--)
if (*E == '\n')
LineCount++;
- for (; LineCount < 2; LineCount++)
- *d->End++ = '\n';
+ if (LineCount < 2)
+ {
+ if ((unsigned)(d->End - d->Buffer) >= d->Size)
+ Resize(d->Size + 3);
+ for (; LineCount < 2; LineCount++)
+ *d->End++ = '\n';
+ }
return true;
}
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 7b496ffd8..518d3dbcd 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -95,6 +95,7 @@ class pkgTagFile
bool Fill();
bool Resize();
+ bool Resize(unsigned long long const newSize);
public:
diff --git a/apt-pkg/vendorlist.cc b/apt-pkg/vendorlist.cc
index ecfc7db87..602425624 100644
--- a/apt-pkg/vendorlist.cc
+++ b/apt-pkg/vendorlist.cc
@@ -66,7 +66,7 @@ bool pkgVendorList::CreateList(Configuration& Cnf) /*{{{*/
Configuration Block(Top);
string VendorID = Top->Tag;
vector <struct Vendor::Fingerprint *> *Fingerprints = new vector<Vendor::Fingerprint *>;
- struct Vendor::Fingerprint *Fingerprint = new struct Vendor::Fingerprint;
+ struct Vendor::Fingerprint *Fingerprint = new struct Vendor::Fingerprint();
string Origin = Block.Find("Origin");
Fingerprint->Print = Block.Find("Fingerprint");
diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc
new file mode 100644
index 000000000..af2d0f461
--- /dev/null
+++ b/apt-private/acqprogress.cc
@@ -0,0 +1,309 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: acqprogress.cc,v 1.24 2003/04/27 01:56:48 doogie Exp $
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/acquire-worker.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <iostream>
+#include <unistd.h>
+
+#include "acqprogress.h"
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) :
+ ScreenWidth(ScreenWidth), ID(0), Quiet(Quiet)
+{
+ BlankLine[0] = 0;
+}
+ /*}}}*/
+// AcqTextStatus::Start - Downloading has started /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::Start()
+{
+ pkgAcquireStatus::Start();
+ BlankLine[0] = 0;
+ ID = 1;
+};
+ /*}}}*/
+// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << _("Hit ") << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fetch - An item has started to download /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the short description and the expected size */
+void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+ if (Itm.Owner->Complete == true)
+ return;
+
+ Itm.Owner->ID = ID++;
+
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+};
+ /*}}}*/
+// AcqTextStatus::Done - Completed a download /*{{{*/
+// ---------------------------------------------------------------------
+/* We don't display anything... */
+void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
+// ---------------------------------------------------------------------
+/* We print out the error text */
+void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ // Ignore certain kinds of transient failures (bad code)
+ if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
+ {
+ cout << _("Ign ") << Itm.Description << endl;
+ }
+ else
+ {
+ cout << _("Err ") << Itm.Description << endl;
+ cout << " " << Itm.Owner->ErrorText << endl;
+ }
+
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Stop - Finished downloading /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the bytes downloaded and the overall average line
+ speed */
+void AcqTextStatus::Stop()
+{
+ pkgAcquireStatus::Stop();
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r' << flush;
+
+ if (FetchedBytes != 0 && _error->PendingError() == false)
+ ioprintf(cout,_("Fetched %sB in %s (%sB/s)\n"),
+ SizeToStr(FetchedBytes).c_str(),
+ TimeToStr(ElapsedTime).c_str(),
+ SizeToStr(CurrentCPS).c_str());
+}
+ /*}}}*/
+// AcqTextStatus::Pulse - Regular event pulse /*{{{*/
+// ---------------------------------------------------------------------
+/* This draws the current progress. Each line has an overall percent
+ meter and a per active item status meter along with an overall
+ bandwidth and ETA indicator. */
+bool AcqTextStatus::Pulse(pkgAcquire *Owner)
+{
+ pkgAcquireStatus::Pulse(Owner);
+
+ if (Quiet > 0)
+ return true;
+
+ enum {Long = 0,Medium,Short} Mode = Medium;
+
+ char Buffer[sizeof(BlankLine)];
+ char *End = Buffer + sizeof(Buffer);
+ char *S = Buffer;
+ if (ScreenWidth >= sizeof(Buffer))
+ ScreenWidth = sizeof(Buffer)-1;
+
+ // Put in the percent done
+ sprintf(S,"%.0f%%",((CurrentBytes + CurrentItems)*100.0)/(TotalBytes+TotalItems));
+
+ bool Shown = false;
+ for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
+ I = Owner->WorkerStep(I))
+ {
+ S += strlen(S);
+
+ // There is no item running
+ if (I->CurrentItem == 0)
+ {
+ if (I->Status.empty() == false)
+ {
+ snprintf(S,End-S," [%s]",I->Status.c_str());
+ Shown = true;
+ }
+
+ continue;
+ }
+
+ Shown = true;
+
+ // Add in the short description
+ if (I->CurrentItem->Owner->ID != 0)
+ snprintf(S,End-S," [%lu %s",I->CurrentItem->Owner->ID,
+ I->CurrentItem->ShortDesc.c_str());
+ else
+ snprintf(S,End-S," [%s",I->CurrentItem->ShortDesc.c_str());
+ S += strlen(S);
+
+ // Show the short mode string
+ if (I->CurrentItem->Owner->Mode != 0)
+ {
+ snprintf(S,End-S," %s",I->CurrentItem->Owner->Mode);
+ S += strlen(S);
+ }
+
+ // Add the current progress
+ if (Mode == Long)
+ snprintf(S,End-S," %llu",I->CurrentSize);
+ else
+ {
+ if (Mode == Medium || I->TotalSize == 0)
+ snprintf(S,End-S," %sB",SizeToStr(I->CurrentSize).c_str());
+ }
+ S += strlen(S);
+
+ // Add the total size and percent
+ if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
+ {
+ if (Mode == Short)
+ snprintf(S,End-S," %.0f%%",
+ (I->CurrentSize*100.0)/I->TotalSize);
+ else
+ snprintf(S,End-S,"/%sB %.0f%%",SizeToStr(I->TotalSize).c_str(),
+ (I->CurrentSize*100.0)/I->TotalSize);
+ }
+ S += strlen(S);
+ snprintf(S,End-S,"]");
+ }
+
+ // Show something..
+ if (Shown == false)
+ snprintf(S,End-S,_(" [Working]"));
+
+ /* Put in the ETA and cps meter, block off signals to prevent strangeness
+ during resizing */
+ sigset_t Sigs,OldSigs;
+ sigemptyset(&Sigs);
+ sigaddset(&Sigs,SIGWINCH);
+ sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
+
+ if (CurrentCPS != 0)
+ {
+ char Tmp[300];
+ unsigned long long ETA = (TotalBytes - CurrentBytes)/CurrentCPS;
+ sprintf(Tmp," %sB/s %s",SizeToStr(CurrentCPS).c_str(),TimeToStr(ETA).c_str());
+ unsigned int Len = strlen(Buffer);
+ unsigned int LenT = strlen(Tmp);
+ if (Len + LenT < ScreenWidth)
+ {
+ memset(Buffer + Len,' ',ScreenWidth - Len);
+ strcpy(Buffer + ScreenWidth - LenT,Tmp);
+ }
+ }
+ Buffer[ScreenWidth] = 0;
+ BlankLine[ScreenWidth] = 0;
+ sigprocmask(SIG_SETMASK,&OldSigs,0);
+
+ // Draw the current status
+ if (_config->FindB("Apt::Color", false) == true)
+ cout << _config->Find("APT::Color::Yellow");
+ if (strlen(Buffer) == strlen(BlankLine))
+ cout << '\r' << Buffer << flush;
+ else
+ cout << '\r' << BlankLine << '\r' << Buffer << flush;
+ if (_config->FindB("Apt::Color", false) == true)
+ cout << _config->Find("APT::Color::Neutral");
+
+ memset(BlankLine,' ',strlen(Buffer));
+ BlankLine[strlen(Buffer)] = 0;
+
+ Update = false;
+
+ return true;
+}
+ /*}}}*/
+// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
+// ---------------------------------------------------------------------
+/* Prompt for a media swap */
+bool AcqTextStatus::MediaChange(string Media,string Drive)
+{
+ // If we do not output on a terminal and one of the options to avoid user
+ // interaction is given, we assume that no user is present who could react
+ // on your media change request
+ if (isatty(STDOUT_FILENO) != 1 && Quiet >= 2 &&
+ (_config->FindB("APT::Get::Assume-Yes",false) == true ||
+ _config->FindB("APT::Get::Force-Yes",false) == true ||
+ _config->FindB("APT::Get::Trivial-Only",false) == true))
+
+ return false;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+ ioprintf(cout,_("Media change: please insert the disc labeled\n"
+ " '%s'\n"
+ "in the drive '%s' and press enter\n"),
+ Media.c_str(),Drive.c_str());
+
+ char C = 0;
+ bool bStatus = true;
+ while (C != '\n' && C != '\r')
+ {
+ int len = read(STDIN_FILENO,&C,1);
+ if(C == 'c' || len <= 0)
+ bStatus = false;
+ }
+
+ if(bStatus)
+ Update = true;
+ return bStatus;
+}
+ /*}}}*/
diff --git a/apt-private/acqprogress.h b/apt-private/acqprogress.h
new file mode 100644
index 000000000..e47bfb72d
--- /dev/null
+++ b/apt-private/acqprogress.h
@@ -0,0 +1,38 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef ACQPROGRESS_H
+#define ACQPROGRESS_H
+
+#include <apt-pkg/acquire.h>
+
+#include <string>
+
+class AcqTextStatus : public pkgAcquireStatus
+{
+ unsigned int &ScreenWidth;
+ char BlankLine[1024];
+ unsigned long ID;
+ unsigned long Quiet;
+
+ public:
+
+ virtual bool MediaChange(std::string Media,std::string Drive);
+ virtual void IMSHit(pkgAcquire::ItemDesc &Itm);
+ virtual void Fetch(pkgAcquire::ItemDesc &Itm);
+ virtual void Done(pkgAcquire::ItemDesc &Itm);
+ virtual void Fail(pkgAcquire::ItemDesc &Itm);
+ virtual void Start();
+ virtual void Stop();
+
+ bool Pulse(pkgAcquire *Owner);
+
+ AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet);
+};
+
+#endif
diff --git a/apt-private/makefile b/apt-private/makefile
new file mode 100644
index 000000000..8feb1ce6c
--- /dev/null
+++ b/apt-private/makefile
@@ -0,0 +1,28 @@
+# -*- make -*-
+BASE=..
+SUBDIR=apt-private
+
+# Header location
+HEADER_TARGETDIRS = apt-private
+
+# Bring in the default rules
+include ../buildlib/defaults.mak
+
+# The library name and version (indirectly used from init.h)
+include ../buildlib/libversion.mak
+
+# The library name
+LIBRARY=apt-private
+MAJOR=0.0
+MINOR=0
+SLIBS=$(PTHREADLIB) -lapt-pkg
+
+PRIVATES=list install output cachefile cacheset update upgrade cmndline moo search show main
+SOURCE += $(foreach private, $(PRIVATES), private-$(private).cc)
+HEADERS += $(foreach private, $(PRIVATES), private-$(private).h)
+
+SOURCE+= acqprogress.cc
+HEADERS+= acqprogress.h private-cacheset.h
+
+HEADERS := $(addprefix apt-private/,$(HEADERS))
+include $(LIBRARY_H)
diff --git a/apt-private/private-cachefile.cc b/apt-private/private-cachefile.cc
new file mode 100644
index 000000000..25f65ef09
--- /dev/null
+++ b/apt-private/private-cachefile.cc
@@ -0,0 +1,109 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/error.h>
+
+#include <cstdlib>
+
+#include "private-output.h"
+#include "private-cachefile.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+// CacheFile::NameComp - QSort compare by name /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCache *CacheFile::SortCache = 0;
+int CacheFile::NameComp(const void *a,const void *b)
+{
+ if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
+ return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
+
+ const pkgCache::Package &A = **(pkgCache::Package **)a;
+ const pkgCache::Package &B = **(pkgCache::Package **)b;
+
+ return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
+}
+ /*}}}*/
+// CacheFile::Sort - Sort by name /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void CacheFile::Sort()
+{
+ delete [] List;
+ List = new pkgCache::Package *[Cache->Head().PackageCount];
+ memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
+ pkgCache::PkgIterator I = Cache->PkgBegin();
+ for (;I.end() != true; ++I)
+ List[I->ID] = I;
+
+ SortCache = *this;
+ qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
+}
+ /*}}}*/
+// CacheFile::CheckDeps - Open the cache file /*{{{*/
+// ---------------------------------------------------------------------
+/* This routine generates the caches and then opens the dependency cache
+ and verifies that the system is OK. */
+bool CacheFile::CheckDeps(bool AllowBroken)
+{
+ bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
+
+ if (_error->PendingError() == true)
+ return false;
+
+ // Check that the system is OK
+ if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
+ return _error->Error("Internal error, non-zero counts");
+
+ // Apply corrections for half-installed packages
+ if (pkgApplyStatus(*DCache) == false)
+ return false;
+
+ if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
+ {
+ FixBroken = true;
+ if ((DCache->PolicyBrokenCount() > 0))
+ {
+ // upgrade all policy-broken packages with ForceImportantDeps=True
+ for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I)
+ if ((*DCache)[I].NowPolicyBroken() == true)
+ DCache->MarkInstall(I,true,0, false, true);
+ }
+ }
+
+ // Nothing is broken
+ if (DCache->BrokenCount() == 0 || AllowBroken == true)
+ return true;
+
+ // Attempt to fix broken things
+ if (FixBroken == true)
+ {
+ c1out << _("Correcting dependencies...") << flush;
+ if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
+ {
+ c1out << _(" failed.") << endl;
+ ShowBroken(c1out,*this,true);
+
+ return _error->Error(_("Unable to correct dependencies"));
+ }
+ if (pkgMinimizeUpgrade(*DCache) == false)
+ return _error->Error(_("Unable to minimize the upgrade set"));
+
+ c1out << _(" Done") << endl;
+ }
+ else
+ {
+ c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
+ ShowBroken(c1out,*this,true);
+
+ return _error->Error(_("Unmet dependencies. Try using -f."));
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-cachefile.h b/apt-private/private-cachefile.h
new file mode 100644
index 000000000..f24d93020
--- /dev/null
+++ b/apt-private/private-cachefile.h
@@ -0,0 +1,51 @@
+#ifndef APT_PRIVATE_CACHEFILE_H
+#define APT_PRIVATE_CACHEFILE_H
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/progress.h>
+
+
+// class CacheFile - Cover class for some dependency cache functions /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+class CacheFile : public pkgCacheFile
+{
+ static pkgCache *SortCache;
+ static int NameComp(const void *a,const void *b);
+
+ public:
+ pkgCache::Package **List;
+
+ void Sort();
+ bool CheckDeps(bool AllowBroken = false);
+ bool BuildCaches(bool WithLock = true)
+ {
+ OpTextProgress Prog(*_config);
+ if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false)
+ return false;
+ return true;
+ }
+ bool Open(bool WithLock = true)
+ {
+ OpTextProgress Prog(*_config);
+ if (pkgCacheFile::Open(&Prog,WithLock) == false)
+ return false;
+ Sort();
+
+ return true;
+ };
+ bool OpenForInstall()
+ {
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ return Open(false);
+ else
+ return Open(true);
+ }
+ CacheFile() : List(0) {};
+ ~CacheFile() {
+ delete[] List;
+ }
+};
+ /*}}}*/
+
+#endif
diff --git a/apt-private/private-cacheset.cc b/apt-private/private-cacheset.cc
new file mode 100644
index 000000000..6fb224010
--- /dev/null
+++ b/apt-private/private-cacheset.cc
@@ -0,0 +1,63 @@
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/strutl.h>
+
+#include "private-cacheset.h"
+
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ OpProgress &progress)
+{
+ Matcher null_matcher = Matcher();
+ return GetLocalitySortedVersionSet(CacheFile, output_set,
+ null_matcher, progress);
+}
+
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ Matcher &matcher,
+ OpProgress &progress)
+{
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+
+ int Done=0;
+ progress.SubProgress(Cache->Head().PackageCount, _("Sorting"));
+ for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+ {
+ if (Done%500 == 0)
+ progress.Progress(Done);
+ Done++;
+
+ if ((matcher)(P) == false)
+ continue;
+
+ // exclude virtual pkgs
+ if (P.VersionList() == 0)
+ continue;
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+ if (_config->FindB("APT::Cmd::Installed") == true)
+ {
+ if (P.CurrentVer() != NULL)
+ {
+ output_set.insert(P.CurrentVer());
+ }
+ }
+ else if (_config->FindB("APT::Cmd::Upgradable") == true)
+ {
+ if(P.CurrentVer() && state.Upgradable())
+ {
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ output_set.insert(policy->GetCandidateVer(P));
+ }
+ }
+ else
+ {
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ output_set.insert(policy->GetCandidateVer(P));
+ }
+ }
+ progress.Done();
+ return true;
+}
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h
new file mode 100644
index 000000000..15b531e9d
--- /dev/null
+++ b/apt-private/private-cacheset.h
@@ -0,0 +1,265 @@
+#ifndef APT_PRIVATE_CACHESET_H
+#define APT_PRIVATE_CACHESET_H
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+
+#include <algorithm>
+#include <vector>
+
+#include "private-output.h"
+
+#include <apti18n.h>
+
+struct VersionSortDescriptionLocality
+{
+ bool operator () (const pkgCache::VerIterator &v_lhs,
+ const pkgCache::VerIterator &v_rhs)
+ {
+ pkgCache::DescFile *A = v_lhs.TranslatedDescription().FileList();
+ pkgCache::DescFile *B = v_rhs.TranslatedDescription().FileList();
+ if (A == 0 && B == 0)
+ return false;
+
+ if (A == 0)
+ return true;
+
+ if (B == 0)
+ return false;
+
+ if (A->File == B->File)
+ return A->Offset < B->Offset;
+
+ return A->File < B->File;
+ }
+};
+
+// sorted by locality which makes iterating much faster
+typedef APT::VersionContainer<
+ std::set<pkgCache::VerIterator,
+ VersionSortDescriptionLocality> > LocalitySortedVersionSet;
+
+class Matcher {
+public:
+ virtual bool operator () (const pkgCache::PkgIterator &P) {
+ return true;};
+};
+
+// FIXME: add default argument for OpProgress (or overloaded function)
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ Matcher &matcher,
+ OpProgress &progress);
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ OpProgress &progress);
+
+
+// CacheSetHelper saving virtual packages /*{{{*/
+class CacheSetHelperVirtuals: public APT::CacheSetHelper {
+public:
+ APT::PackageSet virtualPkgs;
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotFindCandidateVer(Cache, Pkg);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotFindNewestVer(Cache, Pkg);
+ }
+
+ virtual void canNotFindAllVer(APT::VersionContainerInterface * vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ CacheSetHelper::canNotFindAllVer(vci, Cache, Pkg);
+ }
+
+ CacheSetHelperVirtuals(bool const ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {}
+};
+ /*}}}*/
+
+// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
+class CacheSetHelperAPTGet : public APT::CacheSetHelper {
+ /** \brief stream message should be printed to */
+ std::ostream &out;
+ /** \brief were things like Task or RegEx used to select packages? */
+ bool explicitlyNamed;
+
+ APT::PackageSet virtualPkgs;
+
+public:
+ std::list<std::pair<pkgCache::VerIterator, std::string> > selectedByRelease;
+
+ CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
+ explicitlyNamed = true;
+ }
+
+ virtual void showTaskSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern) {
+ ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showRegExSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern) {
+ ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ std::string const &ver, bool const verIsRel) {
+ if (ver == Ver.VerStr())
+ return;
+ selectedByRelease.push_back(make_pair(Ver, ver));
+ }
+
+ bool showVirtualPackageErrors(pkgCacheFile &Cache) {
+ if (virtualPkgs.empty() == true)
+ return true;
+ for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
+ Pkg != virtualPkgs.end(); ++Pkg) {
+ if (Pkg->ProvidesList != 0) {
+ ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
+ Pkg.FullName(true).c_str());
+
+ pkgCache::PrvIterator I = Pkg.ProvidesList();
+ unsigned short provider = 0;
+ for (; I.end() == false; ++I) {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
+ c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
+ if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+ c1out << _(" [Installed]");
+ c1out << std::endl;
+ ++provider;
+ }
+ }
+ // if we found no candidate which provide this package, show non-candidates
+ if (provider == 0)
+ for (I = Pkg.ProvidesList(); I.end() == false; ++I)
+ c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
+ << _(" [Not candidate version]") << std::endl;
+ else
+ out << _("You should explicitly select one to install.") << std::endl;
+ } else {
+ ioprintf(c1out,
+ _("Package %s is not available, but is referred to by another package.\n"
+ "This may mean that the package is missing, has been obsoleted, or\n"
+ "is only available from another source\n"),Pkg.FullName(true).c_str());
+
+ std::string List;
+ std::string VersionsList;
+ SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
+ memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
+ for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
+ Dep.end() == false; ++Dep) {
+ if (Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ if (Seen[Dep.ParentPkg()->ID] == true)
+ continue;
+ Seen[Dep.ParentPkg()->ID] = true;
+ List += Dep.ParentPkg().FullName(true) + " ";
+ //VersionsList += std::string(Dep.ParentPkg().CurVersion) + "\n"; ???
+ }
+ ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
+ }
+ c1out << std::endl;
+ }
+ return false;
+ }
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ else if (ShowError == true) {
+ _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ if (Pkg->ProvidesList != 0)
+ {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true)
+ ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+ }
+ else
+ {
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ pkgCache::PkgIterator P = Grp.PackageList();
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if (P == Pkg)
+ continue;
+ if (P->CurrentVer != 0) {
+ // TRANSLATORS: Note, this is not an interactive question
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+ Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+ break;
+ }
+ }
+ if (P.end() == true)
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+ APT::VersionSet::Version const &select) {
+ /* This is a pure virtual package and there is a single available
+ candidate providing it. */
+ if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
+ return APT::VersionSet();
+
+ pkgCache::PkgIterator Prov;
+ bool found_one = false;
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+ pkgCache::VerIterator const PVer = P.OwnerVer();
+ pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+ /* Ignore versions that are not a candidate. */
+ if (Cache[PPkg].CandidateVer != PVer)
+ continue;
+
+ if (found_one == false) {
+ Prov = PPkg;
+ found_one = true;
+ } else if (PPkg != Prov) {
+ // same group, so it's a foreign package
+ if (PPkg->Group == Prov->Group) {
+ // do we already have the requested arch?
+ if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
+ strcmp(Prov.Arch(), "all") == 0 ||
+ unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
+ continue;
+ // see which architecture we prefer more and switch to it
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
+ Prov = PPkg;
+ continue;
+ }
+ found_one = false; // we found at least two
+ break;
+ }
+ }
+
+ if (found_one == true) {
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+ }
+ return APT::VersionSet();
+ }
+
+ inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
+
+};
+ /*}}}*/
+
+#endif
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
new file mode 100644
index 000000000..aceb865d5
--- /dev/null
+++ b/apt-private/private-cmndline.cc
@@ -0,0 +1,268 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
+
+#include <vector>
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "private-cmndline.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+bool strcmp_match_in_list(char const * const Cmd, ...) /*{{{*/
+{
+ va_list args;
+ bool found = false;
+ va_start(args, Cmd);
+ char const * Match = NULL;
+ while ((Match = va_arg(args, char const *)) != NULL)
+ {
+ if (strcmp(Cmd, Match) != 0)
+ continue;
+ found = true;
+ break;
+ }
+ va_end(args);
+ return found;
+}
+ /*}}}*/
+#define addArg(w,x,y,z) Args.push_back(CommandLine::MakeArgs(w,x,y,z))
+#define CmdMatches(...) strcmp_match_in_list(Cmd, __VA_ARGS__, NULL)
+bool addArgumentsAPTCache(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("depends", "rdepends", "xvcg", "dotty"))
+ {
+ addArg('i', "important", "APT::Cache::Important", 0);
+ addArg(0, "installed", "APT::Cache::Installed", 0);
+ addArg(0, "pre-depends", "APT::Cache::ShowPre-Depends", 0);
+ addArg(0, "depends", "APT::Cache::ShowDepends", 0);
+ addArg(0, "recommends", "APT::Cache::ShowRecommends", 0);
+ addArg(0, "suggests", "APT::Cache::ShowSuggests", 0);
+ addArg(0, "replaces", "APT::Cache::ShowReplaces", 0);
+ addArg(0, "breaks", "APT::Cache::ShowBreaks", 0);
+ addArg(0, "conflicts", "APT::Cache::ShowConflicts", 0);
+ addArg(0, "enhances", "APT::Cache::ShowEnhances", 0);
+ addArg(0, "recurse", "APT::Cache::RecurseDepends", 0);
+ }
+ else if (CmdMatches("search"))
+ {
+ addArg('n', "names-only", "APT::Cache::NamesOnly", 0);
+ addArg('f', "full", "APT::Cache::ShowFull", 0);
+ }
+ else if (CmdMatches("show"))
+ {
+ addArg('a', "all-versions", "APT::Cache::AllVersions", 0);
+ }
+ else if (CmdMatches("pkgnames"))
+ {
+ addArg(0, "all-names", "APT::Cache::AllNames", 0);
+ }
+ else if (CmdMatches("gencaches", "showsrc", "showpkg", "stats", "dump",
+ "dumpavail", "unmet", "showauto", "policy", "madison"))
+ ;
+ else
+ return false;
+
+ // FIXME: move to the correct command(s)
+ addArg('g', "generate", "APT::Cache::Generate", 0);
+ addArg('t', "target-release", "APT::Default-Release", CommandLine::HasArg);
+ addArg('t', "default-release", "APT::Default-Release", CommandLine::HasArg);
+
+ addArg('p', "pkg-cache", "Dir::Cache::pkgcache", CommandLine::HasArg);
+ addArg('s', "src-cache", "Dir::Cache::srcpkgcache", CommandLine::HasArg);
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTCDROM(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("add", "ident") == false)
+ return false;
+
+ // FIXME: move to the correct command(s)
+ addArg(0, "auto-detect", "Acquire::cdrom::AutoDetect", CommandLine::Boolean);
+ addArg('d', "cdrom", "Acquire::cdrom::mount", CommandLine::HasArg);
+ addArg('r', "rename", "APT::CDROM::Rename", 0);
+ addArg('m', "no-mount", "APT::CDROM::NoMount", 0);
+ addArg('f', "fast", "APT::CDROM::Fast", 0);
+ addArg('n', "just-print", "APT::CDROM::NoAct", 0);
+ addArg('n', "recon", "APT::CDROM::NoAct", 0);
+ addArg('n', "no-act", "APT::CDROM::NoAct", 0);
+ addArg('a', "thorough", "APT::CDROM::Thorough", 0);
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTConfig(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("dump"))
+ {
+ addArg(0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean);
+ addArg(0,"format","APT::Config::Dump::Format",CommandLine::HasArg);
+ }
+ else if (CmdMatches("shell"))
+ ;
+ else
+ return false;
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade",
+ "deselect-upgrade", "autoremove"))
+ {
+ addArg(0, "dpkg-progress", "DpkgPM::Progress", 0);
+ addArg('f', "fix-broken", "APT::Get::Fix-Broken", 0);
+ addArg(0, "purge", "APT::Get::Purge", 0);
+ addArg('V',"verbose-versions","APT::Get::Show-Versions",0);
+ addArg(0, "auto-remove", "APT::Get::AutomaticRemove", 0);
+ addArg(0, "reinstall", "APT::Get::ReInstall", 0);
+ addArg(0, "solver", "APT::Solver", CommandLine::HasArg);
+ if (CmdMatches("upgrade"))
+ {
+ addArg(0, "allow-new", "APT::Get::UpgradeAllowNew", 0);
+ }
+ }
+ else if (CmdMatches("update"))
+ {
+ addArg(0, "list-cleanup", "APT::Get::List-Cleanup", 0);
+ }
+ else if (CmdMatches("source"))
+ {
+ addArg('b', "compile", "APT::Get::Compile", 0);
+ addArg('b', "build", "APT::Get::Compile", 0);
+ addArg(0, "diff-only", "APT::Get::Diff-Only", 0);
+ addArg(0, "debian-only", "APT::Get::Diff-Only", 0);
+ addArg(0, "tar-only", "APT::Get::Tar-Only", 0);
+ addArg(0, "dsc-only", "APT::Get::Dsc-Only", 0);
+ }
+ else if (CmdMatches("build-dep"))
+ {
+ addArg('a', "host-architecture", "APT::Get::Host-Architecture", CommandLine::HasArg);
+ addArg(0, "solver", "APT::Solver", CommandLine::HasArg);
+ }
+ else if (CmdMatches("clean", "autoclean", "check", "download", "changelog") ||
+ CmdMatches("markauto", "unmarkauto")) // deprecated commands
+ ;
+ else if (CmdMatches("moo"))
+ addArg(0, "color", "APT::Moo::Color", 0);
+
+ if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade",
+ "deselect-upgrade", "autoremove", "clean", "autoclean", "check",
+ "build-dep"))
+ {
+ addArg('s', "simulate", "APT::Get::Simulate", 0);
+ addArg('s', "just-print", "APT::Get::Simulate", 0);
+ addArg('s', "recon", "APT::Get::Simulate", 0);
+ addArg('s', "dry-run", "APT::Get::Simulate", 0);
+ addArg('s', "no-act", "APT::Get::Simulate", 0);
+ }
+
+ // FIXME: move to the correct command(s)
+ addArg('d',"download-only","APT::Get::Download-Only",0);
+ addArg('y',"yes","APT::Get::Assume-Yes",0);
+ addArg('y',"assume-yes","APT::Get::Assume-Yes",0);
+ addArg(0,"assume-no","APT::Get::Assume-No",0);
+ addArg('u',"show-upgraded","APT::Get::Show-Upgraded",0);
+ addArg('m',"ignore-missing","APT::Get::Fix-Missing",0);
+ addArg('t',"target-release","APT::Default-Release",CommandLine::HasArg);
+ addArg('t',"default-release","APT::Default-Release",CommandLine::HasArg);
+ addArg(0,"download","APT::Get::Download",0);
+ addArg(0,"fix-missing","APT::Get::Fix-Missing",0);
+ addArg(0,"ignore-hold","APT::Ignore-Hold",0);
+ addArg(0,"upgrade","APT::Get::upgrade",0);
+ addArg(0,"only-upgrade","APT::Get::Only-Upgrade",0);
+ addArg(0,"force-yes","APT::Get::force-yes",0);
+ addArg(0,"print-uris","APT::Get::Print-URIs",0);
+ addArg(0,"trivial-only","APT::Get::Trivial-Only",0);
+ addArg(0,"remove","APT::Get::Remove",0);
+ addArg(0,"only-source","APT::Get::Only-Source",0);
+ addArg(0,"arch-only","APT::Get::Arch-Only",0);
+ addArg(0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0);
+ addArg(0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean);
+ addArg(0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean);
+ addArg(0,"fix-policy","APT::Get::Fix-Policy-Broken",0);
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTMark(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("auto", "manual", "hold", "unhold", "showauto",
+ "showmanual", "showhold", "showholds", "install",
+ "markauto", "unmarkauto"))
+ ;
+ else
+ return false;
+
+ addArg('v',"verbose","APT::MarkAuto::Verbose",0);
+ addArg('s',"simulate","APT::Mark::Simulate",0);
+ addArg('s',"just-print","APT::Mark::Simulate",0);
+ addArg('s',"recon","APT::Mark::Simulate",0);
+ addArg('s',"dry-run","APT::Mark::Simulate",0);
+ addArg('s',"no-act","APT::Mark::Simulate",0);
+ addArg('f',"file","Dir::State::extended_states",CommandLine::HasArg);
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPT(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("list"))
+ {
+ addArg(0,"installed","APT::Cmd::Installed",0);
+ addArg(0,"upgradable","APT::Cmd::Upgradable",0);
+ addArg('a', "all-versions", "APT::Cmd::AllVersions", 0);
+ }
+ else if (addArgumentsAPTGet(Args, Cmd) || addArgumentsAPTCache(Args, Cmd))
+ {
+ // we have no (supported) command-name overlaps so far, so we call
+ // specifics in order until we find one which adds arguments
+ }
+ else
+ return false;
+
+ return true;
+}
+ /*}}}*/
+std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char const * const Cmd)/*{{{*/
+{
+ std::vector<CommandLine::Args> Args;
+ Args.reserve(50);
+ if (Program == NULL || Cmd == NULL)
+ ; // FIXME: Invalid command supplied
+ else if (strcmp(Cmd, "help") == 0)
+ ; // no options for help so no need to implement it in each
+ else if (strcmp(Program, "apt-get") == 0)
+ addArgumentsAPTGet(Args, Cmd);
+ else if (strcmp(Program, "apt-cache") == 0)
+ addArgumentsAPTCache(Args, Cmd);
+ else if (strcmp(Program, "apt-cdrom") == 0)
+ addArgumentsAPTCDROM(Args, Cmd);
+ else if (strcmp(Program, "apt-config") == 0)
+ addArgumentsAPTConfig(Args, Cmd);
+ else if (strcmp(Program, "apt-mark") == 0)
+ addArgumentsAPTMark(Args, Cmd);
+ else if (strcmp(Program, "apt") == 0)
+ addArgumentsAPT(Args, Cmd);
+
+ // options without a command
+ addArg('h', "help", "help", 0);
+ addArg('v', "version", "version", 0);
+ // general options
+ addArg('q', "quiet", "quiet", CommandLine::IntLevel);
+ addArg('q', "silent", "quiet", CommandLine::IntLevel);
+ addArg('c', "config-file", 0, CommandLine::ConfigFile);
+ addArg('o', "option", 0, CommandLine::ArbItem);
+ addArg(0, NULL, NULL, 0);
+
+ return Args;
+}
+ /*}}}*/
+#undef CmdMatches
+#undef addArg
diff --git a/apt-private/private-cmndline.h b/apt-private/private-cmndline.h
new file mode 100644
index 000000000..76045ffe7
--- /dev/null
+++ b/apt-private/private-cmndline.h
@@ -0,0 +1,10 @@
+#ifndef APT_PRIVATE_CMNDLINE_H
+#define APT_PRIVATE_CMNDLINE_H
+
+#include <apt-pkg/cmndline.h>
+
+#include <vector>
+
+std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char const * const Cmd);
+
+#endif
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
new file mode 100644
index 000000000..d5052fcc0
--- /dev/null
+++ b/apt-private/private-install.cc
@@ -0,0 +1,852 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/versionmatch.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
+
+#include <set>
+#include <locale.h>
+#include <langinfo.h>
+#include <fstream>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <regex.h>
+#include <sys/wait.h>
+#include <sstream>
+
+#include "private-install.h"
+#include "private-cachefile.h"
+#include "private-output.h"
+#include "private-cacheset.h"
+#include "acqprogress.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+// CheckAuth - check if each download comes form a trusted source /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+static bool CheckAuth(pkgAcquire& Fetcher)
+{
+ std::string UntrustedList;
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
+ {
+ if (!(*I)->IsTrusted())
+ {
+ UntrustedList += std::string((*I)->ShortDesc()) + " ";
+ }
+ }
+
+ if (UntrustedList == "")
+ {
+ return true;
+ }
+
+ ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
+
+ if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
+ {
+ c2out << _("Authentication warning overridden.\n");
+ return true;
+ }
+
+ if (_config->FindI("quiet",0) < 2
+ && _config->FindB("APT::Get::Assume-Yes",false) == false)
+ {
+ c2out << _("Install these packages without verification?") << std::flush;
+ if (!YnPrompt(false))
+ return _error->Error(_("Some packages could not be authenticated"));
+
+ return true;
+ }
+ else if (_config->FindB("APT::Get::Force-Yes",false) == true)
+ {
+ return true;
+ }
+
+ return _error->Error(_("There are problems and -y was used without --force-yes"));
+}
+ /*}}}*/
+
+
+// InstallPackages - Actually download and install the packages /*{{{*/
+// ---------------------------------------------------------------------
+/* This displays the informative messages describing what is going to
+ happen and then calls the download routines */
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
+{
+ if (_config->FindB("APT::Get::Purge",false) == true)
+ {
+ pkgCache::PkgIterator I = Cache->PkgBegin();
+ for (; I.end() == false; ++I)
+ {
+ if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
+ Cache->MarkDelete(I,true);
+ }
+ }
+
+ bool Fail = false;
+ bool Essential = false;
+
+ // Show all the various warning indicators
+ ShowDel(c1out,Cache);
+ ShowNew(c1out,Cache);
+ if (ShwKept == true)
+ ShowKept(c1out,Cache);
+ Fail |= !ShowHold(c1out,Cache);
+ if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
+ ShowUpgraded(c1out,Cache);
+ Fail |= !ShowDowngraded(c1out,Cache);
+ if (_config->FindB("APT::Get::Download-Only",false) == false)
+ Essential = !ShowEssential(c1out,Cache);
+ Fail |= Essential;
+ Stats(c1out,Cache);
+
+ // Sanity check
+ if (Cache->BrokenCount() != 0)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
+ }
+
+ if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ Cache->BadCount() == 0)
+ return true;
+
+ // No remove flag
+ if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
+ return _error->Error(_("Packages need to be removed but remove is disabled."));
+
+ // Run the simulator ..
+ if (_config->FindB("APT::Get::Simulate") == true)
+ {
+ pkgSimulate PM(Cache);
+ int status_fd = _config->FindI("APT::Status-Fd",-1);
+ pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
+ if (Res == pkgPackageManager::Failed)
+ return false;
+ if (Res != pkgPackageManager::Completed)
+ return _error->Error(_("Internal error, Ordering didn't finish"));
+ return true;
+ }
+
+ // Create the text record parser
+ pkgRecords Recs(Cache);
+ if (_error->PendingError() == true)
+ return false;
+
+ // Create the download object
+ pkgAcquire Fetcher;
+ AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+ if (_config->FindB("APT::Get::Print-URIs", false) == true)
+ {
+ // force a hashsum for compatibility reasons
+ _config->CndSet("Acquire::ForceHash", "md5sum");
+ }
+ else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
+ return false;
+
+ // Read the source list
+ if (Cache.BuildSourceList() == false)
+ return false;
+ pkgSourceList *List = Cache.GetSourceList();
+
+ // Create the package manager and prepare to download
+ SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
+ if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
+ _error->PendingError() == true)
+ return false;
+
+ // Display statistics
+ unsigned long long FetchBytes = Fetcher.FetchNeeded();
+ unsigned long long FetchPBytes = Fetcher.PartialPresent();
+ unsigned long long DebBytes = Fetcher.TotalNeeded();
+ if (DebBytes != Cache->DebSize())
+ {
+ c0out << DebBytes << ',' << Cache->DebSize() << std::endl;
+ c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << std::endl;
+ }
+
+ // Number of bytes
+ if (DebBytes != FetchBytes)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
+ SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
+ else if (DebBytes != 0)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("Need to get %sB of archives.\n"),
+ SizeToStr(DebBytes).c_str());
+
+ // Size delta
+ if (Cache->UsrSize() >= 0)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
+ SizeToStr(Cache->UsrSize()).c_str());
+ else
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
+ SizeToStr(-1*Cache->UsrSize()).c_str());
+
+ if (_error->PendingError() == true)
+ return false;
+
+ /* Check for enough free space, but only if we are actually going to
+ download */
+ if (_config->FindB("APT::Get::Print-URIs") == false &&
+ _config->FindB("APT::Get::Download",true) == true)
+ {
+ struct statvfs Buf;
+ std::string OutputDir = _config->FindDir("Dir::Cache::Archives");
+ if (statvfs(OutputDir.c_str(),&Buf) != 0) {
+ if (errno == EOVERFLOW)
+ return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
+ OutputDir.c_str());
+ else
+ return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+ OutputDir.c_str());
+ } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+ {
+ struct statfs Stat;
+ if (statfs(OutputDir.c_str(),&Stat) != 0
+#if HAVE_STRUCT_STATFS_F_TYPE
+ || unsigned(Stat.f_type) != RAMFS_MAGIC
+#endif
+ )
+ return _error->Error(_("You don't have enough free space in %s."),
+ OutputDir.c_str());
+ }
+ }
+
+ // Fail safe check
+ if (_config->FindI("quiet",0) >= 2 ||
+ _config->FindB("APT::Get::Assume-Yes",false) == true)
+ {
+ if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
+ return _error->Error(_("There are problems and -y was used without --force-yes"));
+ }
+
+ if (Essential == true && Safety == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+
+ // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
+ // careful with hard to type or special characters (like non-breaking spaces)
+ const char *Prompt = _("Yes, do as I say!");
+ ioprintf(c2out,
+ _("You are about to do something potentially harmful.\n"
+ "To continue type in the phrase '%s'\n"
+ " ?] "),Prompt);
+ c2out << std::flush;
+ if (AnalPrompt(Prompt) == false)
+ {
+ c2out << _("Abort.") << std::endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ // Prompt to continue
+ if (Ask == true || Fail == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+
+ if (_config->FindI("quiet",0) < 2 &&
+ _config->FindB("APT::Get::Assume-Yes",false) == false)
+ {
+ c2out << _("Do you want to continue?") << std::flush;
+ if (YnPrompt() == false)
+ {
+ c2out << _("Abort.") << std::endl;
+ exit(1);
+ }
+ }
+ }
+ }
+
+ // Just print out the uris an exit if the --print-uris flag was used
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); ++I)
+ c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
+ return true;
+ }
+
+ if (!CheckAuth(Fetcher))
+ return false;
+
+ /* Unlock the dpkg lock if we are not going to be doing an install
+ after. */
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ _system->UnLock();
+
+ // Run it
+ while (1)
+ {
+ bool Transient = false;
+ if (_config->FindB("APT::Get::Download",true) == false)
+ {
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
+ {
+ if ((*I)->Local == true)
+ {
+ ++I;
+ continue;
+ }
+
+ // Close the item and check if it was found in cache
+ (*I)->Finished();
+ if ((*I)->Complete == false)
+ Transient = true;
+
+ // Clear it out of the fetch list
+ delete *I;
+ I = Fetcher.ItemsBegin();
+ }
+ }
+
+ if (Fetcher.Run() == pkgAcquire::Failed)
+ return false;
+
+ // Print out errors
+ bool Failed = false;
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
+ {
+ if ((*I)->Status == pkgAcquire::Item::StatDone &&
+ (*I)->Complete == true)
+ continue;
+
+ if ((*I)->Status == pkgAcquire::Item::StatIdle)
+ {
+ Transient = true;
+ // Failed = true;
+ continue;
+ }
+
+ fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
+ (*I)->ErrorText.c_str());
+ Failed = true;
+ }
+
+ /* If we are in no download mode and missing files and there were
+ 'failures' then the user must specify -m. Furthermore, there
+ is no such thing as a transient error in no-download mode! */
+ if (Transient == true &&
+ _config->FindB("APT::Get::Download",true) == false)
+ {
+ Transient = false;
+ Failed = true;
+ }
+
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ {
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ return _error->Error(_("Some files failed to download"));
+ c1out << _("Download complete and in download only mode") << std::endl;
+ return true;
+ }
+
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ {
+ return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
+ }
+
+ if (Transient == true && Failed == true)
+ return _error->Error(_("--fix-missing and media swapping is not currently supported"));
+
+ // Try to deal with missing package files
+ if (Failed == true && PM->FixMissing() == false)
+ {
+ c2out << _("Unable to correct missing packages.") << std::endl;
+ return _error->Error(_("Aborting install."));
+ }
+
+ _system->UnLock();
+ int status_fd = _config->FindI("APT::Status-Fd",-1);
+ pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
+ if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+ return false;
+ if (Res == pkgPackageManager::Completed)
+ break;
+
+ // Reload the fetcher object and loop again for media swapping
+ Fetcher.Shutdown();
+ if (PM->GetArchives(&Fetcher,List,&Recs) == false)
+ return false;
+
+ _system->Lock();
+ }
+
+ std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
+ if (disappearedPkgs.empty() == true)
+ return true;
+
+ std::string disappear;
+ for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
+ d != disappearedPkgs.end(); ++d)
+ disappear.append(*d).append(" ");
+
+ ShowList(c1out, P_("The following package disappeared from your system as\n"
+ "all files have been overwritten by other packages:",
+ "The following packages disappeared from your system as\n"
+ "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, "");
+ c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl;
+
+ return true;
+}
+ /*}}}*/
+
+
+// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Remove unused automatic packages */
+bool DoAutomaticRemove(CacheFile &Cache)
+{
+ bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
+ bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
+ bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
+
+ pkgDepCache::ActionGroup group(*Cache);
+ if(Debug)
+ std::cout << "DoAutomaticRemove()" << std::endl;
+
+ if (doAutoRemove == true &&
+ _config->FindB("APT::Get::Remove",true) == false)
+ {
+ c1out << _("We are not supposed to delete stuff, can't start "
+ "AutoRemover") << std::endl;
+ return false;
+ }
+
+ bool purgePkgs = _config->FindB("APT::Get::Purge", false);
+ bool smallList = (hideAutoRemove == false &&
+ strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
+
+ unsigned long autoRemoveCount = 0;
+ APT::PackageSet tooMuch;
+ APT::PackageList autoRemoveList;
+ // look over the cache to see what can be removed
+ for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
+ {
+ pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
+ if (Cache[Pkg].Garbage)
+ {
+ if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
+ if(Debug)
+ std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
+
+ if (doAutoRemove)
+ {
+ if(Pkg.CurrentVer() != 0 &&
+ Pkg->CurrentState != pkgCache::State::ConfigFiles)
+ Cache->MarkDelete(Pkg, purgePkgs, 0, false);
+ else
+ Cache->MarkKeep(Pkg, false, false);
+ }
+ else
+ {
+ if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
+ autoRemoveList.insert(Pkg);
+ // if the package is a new install and already garbage we don't need to
+ // install it in the first place, so nuke it instead of show it
+ if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
+ {
+ if (Pkg.CandVersion() != 0)
+ tooMuch.insert(Pkg);
+ Cache->MarkDelete(Pkg, false, 0, false);
+ }
+ // only show stuff in the list that is not yet marked for removal
+ else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
+ ++autoRemoveCount;
+ }
+ }
+ }
+
+ // we could have removed a new dependency of a garbage package,
+ // so check if a reverse depends is broken and if so install it again.
+ if (tooMuch.empty() == false && (Cache->BrokenCount() != 0 || Cache->PolicyBrokenCount() != 0))
+ {
+ bool Changed;
+ do {
+ Changed = false;
+ for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
+ Pkg != tooMuch.end() && Changed == false; ++Pkg)
+ {
+ APT::PackageSet too;
+ too.insert(*Pkg);
+ for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
+ Prv.end() == false; ++Prv)
+ too.insert(Prv.ParentPkg());
+ for (APT::PackageSet::const_iterator P = too.begin();
+ P != too.end() && Changed == false; ++P) {
+ for (pkgCache::DepIterator R = P.RevDependsList();
+ R.end() == false; ++R)
+ {
+ if (R.IsNegative() == true ||
+ Cache->IsImportantDep(R) == false)
+ continue;
+ pkgCache::PkgIterator N = R.ParentPkg();
+ if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
+ continue;
+ if (Debug == true)
+ std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
+ Cache->MarkInstall(Pkg, false, 0, false);
+ if (hideAutoRemove == false)
+ ++autoRemoveCount;
+ tooMuch.erase(Pkg);
+ Changed = true;
+ break;
+ }
+ }
+ }
+ } while (Changed == true);
+ }
+
+ std::string autoremovelist, autoremoveversions;
+ if (smallList == false && autoRemoveCount != 0)
+ {
+ for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
+ {
+ if (Cache[Pkg].Garbage == false)
+ continue;
+ autoremovelist += Pkg.FullName(true) + " ";
+ autoremoveversions += std::string(Cache[Pkg].CandVersion) + "\n";
+ }
+ }
+
+ // Now see if we had destroyed anything (if we had done anything)
+ if (Cache->BrokenCount() != 0)
+ {
+ c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
+ "shouldn't happen. Please file a bug report against apt.") << std::endl;
+ c1out << std::endl;
+ c1out << _("The following information may help to resolve the situation:") << std::endl;
+ c1out << std::endl;
+ ShowBroken(c1out,Cache,false);
+
+ return _error->Error(_("Internal Error, AutoRemover broke stuff"));
+ }
+
+ // if we don't remove them, we should show them!
+ if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
+ {
+ if (smallList == false)
+ ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
+ "The following packages were automatically installed and are no longer required:",
+ autoRemoveCount), autoremovelist, autoremoveversions);
+ else
+ ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
+ "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
+ c1out << P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount) << std::endl;
+ }
+ return true;
+}
+ /*}}}*/
+
+
+
+
+// DoInstall - Install packages from the command line /*{{{*/
+// ---------------------------------------------------------------------
+/* Install named packages */
+bool DoInstall(CommandLine &CmdL)
+{
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false ||
+ Cache.CheckDeps(CmdL.FileSize() != 1) == false)
+ return false;
+
+ // Enter the special broken fixing mode if the user specified arguments
+ bool BrokenFix = false;
+ if (Cache->BrokenCount() != 0)
+ BrokenFix = true;
+
+ pkgProblemResolver* Fix = NULL;
+ if (_config->FindB("APT::Get::CallResolver", true) == true)
+ Fix = new pkgProblemResolver(Cache);
+
+ static const unsigned short MOD_REMOVE = 1;
+ static const unsigned short MOD_INSTALL = 2;
+
+ unsigned short fallback = MOD_INSTALL;
+ if (strcasecmp(CmdL.FileList[0],"remove") == 0)
+ fallback = MOD_REMOVE;
+ else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
+ {
+ _config->Set("APT::Get::Purge", true);
+ fallback = MOD_REMOVE;
+ }
+ else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
+ {
+ _config->Set("APT::Get::AutomaticRemove", "true");
+ fallback = MOD_REMOVE;
+ }
+
+ std::list<APT::VersionSet::Modifier> mods;
+ mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+ mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+ CacheSetHelperAPTGet helper(c0out);
+ std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
+ CmdL.FileList + 1, mods, fallback, helper);
+
+ if (_error->PendingError() == true)
+ {
+ helper.showVirtualPackageErrors(Cache);
+ if (Fix != NULL)
+ delete Fix;
+ return false;
+ }
+
+
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ TryToRemove RemoveAction(Cache, Fix);
+
+ // new scope for the ActionGroup
+ {
+ pkgDepCache::ActionGroup group(Cache);
+ unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
+
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ if (order[i] == MOD_INSTALL)
+ InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
+ else if (order[i] == MOD_REMOVE)
+ RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
+ }
+
+ if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
+ {
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ if (order[i] != MOD_INSTALL)
+ continue;
+ InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
+ InstallAction.doAutoInstall();
+ }
+ }
+
+ if (_error->PendingError() == true)
+ {
+ if (Fix != NULL)
+ delete Fix;
+ return false;
+ }
+
+ /* If we are in the Broken fixing mode we do not attempt to fix the
+ problems. This is if the user invoked install without -f and gave
+ packages */
+ if (BrokenFix == true && Cache->BrokenCount() != 0)
+ {
+ c1out << _("You might want to run 'apt-get -f install' to correct these:") << std::endl;
+ ShowBroken(c1out,Cache,false);
+ if (Fix != NULL)
+ delete Fix;
+ return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
+ }
+
+ if (Fix != NULL)
+ {
+ // Call the scored problem resolver
+ Fix->Resolve(true);
+ delete Fix;
+ }
+
+ // Now we check the state of the packages,
+ if (Cache->BrokenCount() != 0)
+ {
+ c1out <<
+ _("Some packages could not be installed. This may mean that you have\n"
+ "requested an impossible situation or if you are using the unstable\n"
+ "distribution that some required packages have not yet been created\n"
+ "or been moved out of Incoming.") << std::endl;
+ /*
+ if (Packages == 1)
+ {
+ c1out << std::endl;
+ c1out <<
+ _("Since you only requested a single operation it is extremely likely that\n"
+ "the package is simply not installable and a bug report against\n"
+ "that package should be filed.") << std::endl;
+ }
+ */
+
+ c1out << _("The following information may help to resolve the situation:") << std::endl;
+ c1out << std::endl;
+ ShowBroken(c1out,Cache,false);
+ if (_error->PendingError() == true)
+ return false;
+ else
+ return _error->Error(_("Broken packages"));
+ }
+ }
+ if (!DoAutomaticRemove(Cache))
+ return false;
+
+ /* Print out a list of packages that are going to be installed extra
+ to what the user asked */
+ if (Cache->InstCount() != verset[MOD_INSTALL].size())
+ {
+ std::string List;
+ std::string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if ((*Cache)[I].Install() == false)
+ continue;
+ pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
+
+ if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += std::string(Cache[I].CandVersion) + "\n";
+ }
+
+ ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
+ }
+
+ /* Print out a list of suggested and recommended packages */
+ {
+ std::string SuggestsList, RecommendsList;
+ std::string SuggestsVersions, RecommendsVersions;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
+
+ /* Just look at the ones we want to install */
+ if ((*Cache)[Pkg].Install() == false)
+ continue;
+
+ // get the recommends/suggests for the candidate ver
+ pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+ for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
+ {
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End); // advances D
+
+ // FIXME: we really should display a or-group as a or-group to the user
+ // the problem is that ShowList is incapable of doing this
+ std::string RecommendsOrList,RecommendsOrVersions;
+ std::string SuggestsOrList,SuggestsOrVersions;
+ bool foundInstalledInOrGroup = false;
+ for(;;)
+ {
+ /* Skip if package is installed already, or is about to be */
+ std::string target = Start.TargetPkg().FullName(true) + " ";
+ pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
+ if (TarPkg->SelectedState == pkgCache::State::Install ||
+ TarPkg->SelectedState == pkgCache::State::Hold ||
+ Cache[Start.TargetPkg()].Install())
+ {
+ foundInstalledInOrGroup=true;
+ break;
+ }
+
+ /* Skip if we already saw it */
+ if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
+ {
+ foundInstalledInOrGroup=true;
+ break;
+ }
+
+ // this is a dep on a virtual pkg, check if any package that provides it
+ // should be installed
+ if(Start.TargetPkg().ProvidesList() != 0)
+ {
+ pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
+ for (; I.end() == false; ++I)
+ {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() &&
+ Pkg.CurrentVer() != 0)
+ foundInstalledInOrGroup=true;
+ }
+ }
+
+ if (Start->Type == pkgCache::Dep::Suggests)
+ {
+ SuggestsOrList += target;
+ SuggestsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+ }
+
+ if (Start->Type == pkgCache::Dep::Recommends)
+ {
+ RecommendsOrList += target;
+ RecommendsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+ }
+
+ if (Start >= End)
+ break;
+ ++Start;
+ }
+
+ if(foundInstalledInOrGroup == false)
+ {
+ RecommendsList += RecommendsOrList;
+ RecommendsVersions += RecommendsOrVersions;
+ SuggestsList += SuggestsOrList;
+ SuggestsVersions += SuggestsOrVersions;
+ }
+
+ }
+ }
+
+ ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
+ ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
+
+ }
+
+ // if nothing changed in the cache, but only the automark information
+ // we write the StateFile here, otherwise it will be written in
+ // cache.commit()
+ if (InstallAction.AutoMarkChanged > 0 &&
+ Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ Cache->BadCount() == 0 &&
+ _config->FindB("APT::Get::Simulate",false) == false)
+ Cache->writeStateFile(NULL);
+
+ // See if we need to prompt
+ // FIXME: check if really the packages in the set are going to be installed
+ if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
+ return InstallPackages(Cache,false,false);
+
+ return InstallPackages(Cache,false);
+}
+ /*}}}*/
diff --git a/apt-private/private-install.h b/apt-private/private-install.h
new file mode 100644
index 000000000..fcf4cbced
--- /dev/null
+++ b/apt-private/private-install.h
@@ -0,0 +1,181 @@
+#ifndef APT_PRIVATE_INSTALL_H
+#define APT_PRIVATE_INSTALL_H
+
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+
+#include "private-cachefile.h"
+#include "private-output.h"
+
+#include <apti18n.h>
+
+#define RAMFS_MAGIC 0x858458f6
+
+bool DoInstall(CommandLine &Cmd);
+
+
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
+ bool Safety = true);
+
+
+// TryToInstall - Mark a package for installation /*{{{*/
+struct TryToInstall {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+ APT::PackageSet doAutoInstallLater;
+
+ TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const FixBroken) : Cache(&Cache), Fix(PM),
+ FixBroken(FixBroken), AutoMarkChanged(0) {};
+
+ void operator() (pkgCache::VerIterator const &Ver) {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Cache->GetDepCache()->SetCandidateVersion(Ver);
+ pkgDepCache::StateCache &State = (*Cache)[Pkg];
+
+ // Handle the no-upgrade case
+ if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
+ ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
+ Pkg.FullName(true).c_str());
+ // Ignore request for install if package would be new
+ else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
+ Pkg.FullName(true).c_str());
+ else {
+ if (Fix != NULL) {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ }
+ Cache->GetDepCache()->MarkInstall(Pkg,false);
+
+ if (State.Install() == false) {
+ if (_config->FindB("APT::Get::ReInstall",false) == true) {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+ Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->SetReInstall(Pkg, true);
+ } else
+ ioprintf(c1out,_("%s is already the newest version.\n"),
+ Pkg.FullName(true).c_str());
+ }
+
+ // Install it with autoinstalling enabled (if we not respect the minial
+ // required deps or the policy)
+ if (FixBroken == false)
+ doAutoInstallLater.insert(Pkg);
+ }
+
+ // see if we need to fix the auto-mark flag
+ // e.g. apt-get install foo
+ // where foo is marked automatic
+ if (State.Install() == false &&
+ (State.Flags & pkgCache::Flag::Auto) &&
+ _config->FindB("APT::Get::ReInstall",false) == false &&
+ _config->FindB("APT::Get::Only-Upgrade",false) == false &&
+ _config->FindB("APT::Get::Download-Only",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually installed.\n"),
+ Pkg.FullName(true).c_str());
+ Cache->GetDepCache()->MarkAuto(Pkg,false);
+ AutoMarkChanged++;
+ }
+ }
+
+ bool propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > start, std::ostream &out)
+ {
+ for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
+ s != start.end(); ++s)
+ Cache->GetDepCache()->SetCandidateVersion(s->first);
+
+ bool Success = true;
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
+ for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
+ s != start.end(); ++s)
+ {
+ Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache)));
+ // We continue here even if it failed to enhance the ShowBroken output
+ Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed);
+ }
+ for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
+ c != Changed.end(); ++c)
+ {
+ if (c->second.end() == true)
+ ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
+ c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str());
+ else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group)
+ {
+ pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache);
+ ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(),
+ V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str());
+ }
+ }
+ return Success;
+ }
+
+ void doAutoInstall() {
+ for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
+ P != doAutoInstallLater.end(); ++P) {
+ pkgDepCache::StateCache &State = (*Cache)[P];
+ if (State.InstBroken() == false && State.InstPolicyBroken() == false)
+ continue;
+ Cache->GetDepCache()->MarkInstall(P, true);
+ }
+ doAutoInstallLater.clear();
+ }
+};
+ /*}}}*/
+// TryToRemove - Mark a package for removal /*{{{*/
+struct TryToRemove {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool PurgePkgs;
+
+ TryToRemove(pkgCacheFile &Cache, pkgProblemResolver *PM) : Cache(&Cache), Fix(PM),
+ PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
+
+ void operator() (pkgCache::VerIterator const &Ver)
+ {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ if (Fix != NULL)
+ {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Fix->Remove(Pkg);
+ }
+
+ if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
+ (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
+ {
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ pkgCache::PkgIterator P = Grp.PackageList();
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if (P == Pkg)
+ continue;
+ if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
+ {
+ // TRANSLATORS: Note, this is not an interactive question
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+ Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+ break;
+ }
+ }
+ if (P.end() == true)
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+
+ // MarkInstall refuses to install packages on hold
+ Pkg->SelectedState = pkgCache::State::Hold;
+ }
+ else
+ Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
+ }
+};
+ /*}}}*/
+
+
+#endif
diff --git a/apt-private/private-list.cc b/apt-private/private-list.cc
new file mode 100644
index 000000000..c3a21aafc
--- /dev/null
+++ b/apt-private/private-list.cc
@@ -0,0 +1,167 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <algorithm>
+
+#include "private-cmndline.h"
+#include "private-list.h"
+#include "private-output.h"
+#include "private-cacheset.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+struct PackageSortAlphabetic
+{
+ bool operator () (const pkgCache::PkgIterator &p_lhs,
+ const pkgCache::PkgIterator &p_rhs)
+ {
+ const std::string &l_name = p_lhs.FullName(true);
+ const std::string &r_name = p_rhs.FullName(true);
+ return (l_name < r_name);
+ }
+};
+
+#ifdef PACKAGE_MATCHER_ABI_COMPAT
+#define PackageMatcher PackageNameMatchesFnmatch
+#endif
+class PackageNameMatcher : public Matcher
+{
+ public:
+ PackageNameMatcher(const char **patterns)
+ {
+ for(int i=0; patterns[i] != NULL; i++)
+ {
+ std::string pattern = patterns[i];
+#ifdef PACKAGE_MATCHER_ABI_COMPAT
+ APT::CacheFilter::PackageNameMatchesFnmatch *cachefilter = NULL;
+ cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
+#else
+ APT::CacheFilter::PackageMatcher *cachefilter = NULL;
+ if(_config->FindB("APT::Cmd::UseRegexp", false) == true)
+ cachefilter = new APT::CacheFilter::PackageNameMatchesRegEx(pattern);
+ else
+ cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
+#endif
+ filters.push_back(cachefilter);
+ }
+ }
+ virtual ~PackageNameMatcher()
+ {
+ for(J=filters.begin(); J != filters.end(); J++)
+ delete *J;
+ }
+ virtual bool operator () (const pkgCache::PkgIterator &P)
+ {
+ for(J=filters.begin(); J != filters.end(); J++)
+ {
+ APT::CacheFilter::PackageMatcher *cachefilter = *J;
+ if((*cachefilter)(P))
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::vector<APT::CacheFilter::PackageMatcher*> filters;
+ std::vector<APT::CacheFilter::PackageMatcher*>::const_iterator J;
+ #undef PackageMatcher
+};
+
+
+void ListAllVersions(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::PkgIterator P,
+ std::ostream &outs)
+{
+ for (pkgCache::VerIterator Ver = P.VersionList();
+ Ver.end() == false; Ver++)
+ ListSingleVersion(CacheFile, records, Ver, outs);
+}
+
+// list - list package based on criteria /*{{{*/
+// ---------------------------------------------------------------------
+bool List(CommandLine &Cmd)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgRecords records(CacheFile);
+
+ if (unlikely(Cache == NULL))
+ return false;
+
+ const char **patterns;
+ const char *all_pattern[] = { "*", NULL};
+
+ if (strv_length(Cmd.FileList + 1) == 0)
+ {
+ patterns = all_pattern;
+ } else {
+ patterns = Cmd.FileList + 1;
+ }
+
+ std::map<std::string, std::string> output_map;
+ std::map<std::string, std::string>::const_iterator K;
+
+ PackageNameMatcher matcher(patterns);
+ LocalitySortedVersionSet bag;
+ OpTextProgress progress;
+ progress.OverallProgress(0,
+ Cache->Head().PackageCount,
+ Cache->Head().PackageCount,
+ _("Listing"));
+ GetLocalitySortedVersionSet(CacheFile, bag, matcher, progress);
+ for (LocalitySortedVersionSet::iterator V = bag.begin(); V != bag.end(); V++)
+ {
+ std::stringstream outs;
+ if(_config->FindB("APT::Cmd::AllVersions", false) == true)
+ {
+ ListAllVersions(CacheFile, records, V.ParentPkg(), outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ } else {
+ ListSingleVersion(CacheFile, records, V, outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ }
+ }
+
+ // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
+ // output the sorted map
+ for (K = output_map.begin(); K != output_map.end(); K++)
+ std::cout << (*K).second << std::endl;
+
+
+ return true;
+}
+
diff --git a/apt-private/private-list.h b/apt-private/private-list.h
new file mode 100644
index 000000000..6f5aad27a
--- /dev/null
+++ b/apt-private/private-list.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_LIST_H
+#define APT_PRIVATE_LIST_H
+
+#include <apt-pkg/cmndline.h>
+
+bool List(CommandLine &Cmd);
+
+
+#endif
diff --git a/apt-private/private-main.cc b/apt-private/private-main.cc
new file mode 100644
index 000000000..1fdf3f0be
--- /dev/null
+++ b/apt-private/private-main.cc
@@ -0,0 +1,26 @@
+
+#include<unistd.h>
+#include<cstring>
+
+#include <apt-pkg/configuration.h>
+#include "private-main.h"
+
+#include <apti18n.h>
+
+void CheckSimulateMode(CommandLine &CmdL)
+{
+ // simulate user-friendly if apt-get has no root privileges
+ if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true &&
+ (CmdL.FileSize() == 0 ||
+ (strcmp(CmdL.FileList[0], "source") != 0 && strcmp(CmdL.FileList[0], "download") != 0 &&
+ strcmp(CmdL.FileList[0], "changelog") != 0)))
+ {
+ if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
+ std::cout << _("NOTE: This is only a simulation!\n"
+ " apt-get needs root privileges for real execution.\n"
+ " Keep also in mind that locking is deactivated,\n"
+ " so don't depend on the relevance to the real current situation!"
+ ) << std::endl;
+ _config->Set("Debug::NoLocking",true);
+ }
+}
diff --git a/apt-private/private-main.h b/apt-private/private-main.h
new file mode 100644
index 000000000..f9a95c4ec
--- /dev/null
+++ b/apt-private/private-main.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_MAIN_H
+#define APT_PRIVATE_MAIN_H
+
+#include <apt-pkg/cmndline.h>
+
+void CheckSimulateMode(CommandLine &CmdL);
+
+
+#endif
diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc
new file mode 100644
index 000000000..9b5b94654
--- /dev/null
+++ b/apt-private/private-moo.cc
@@ -0,0 +1,193 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Here be cows – but: Never ask, never tell
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+
+#include <strings.h>
+#include <sstream>
+
+#include "private-moo.h"
+#include "private-output.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+std::string getMooLine() { /*{{{*/
+ time_t const timenow = time(NULL);
+ struct tm special;
+ localtime_r(&timenow, &special);
+ enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line;
+ if (special.tm_mon == 11 && special.tm_mday == 25)
+ line = PACKAGEMANAGER;
+ else if (special.tm_mon == 7 && special.tm_mday == 16)
+ line = APPRECIATION;
+ else if (special.tm_mon == 10 && special.tm_mday == 7)
+ line = AGITATION;
+ else if (special.tm_mon == 1 && special.tm_mday == 18)
+ line = AIRBORN;
+ else
+ line = NORMAL;
+
+ bool const quiet = _config->FindI("quiet") >= 2;
+ std::ostringstream out;
+ if (quiet == false)
+ out << "...\"";
+
+ switch(line)
+ {
+ case PACKAGEMANAGER: out << "Happy package management day!"; break;
+ case APPRECIATION: out << "Three moos for Debian!"; break;
+ case AGITATION: out << "Whoever needs milk, bows to the animal."; break;
+ case AIRBORN: out << "It's a Bird ... It's a Plane ... It's Super Cow!"; break;
+ default: out << "Have you mooed today?"; break;
+ }
+
+ if (quiet == true)
+ out << std::endl;
+ else
+ out << "\"..." << std::endl;
+
+ return out.str();
+}
+ /*}}}*/
+bool printMooLine() { /*{{{*/
+ std::cerr << getMooLine() << std::endl;
+ return true;
+}
+ /*}}}*/
+bool DoMoo1(CommandLine &CmdL) /*{{{*/
+{
+ // our trustworthy super cow since 2001
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/4;
+ c1out <<
+ OutputInDepth(depth, " ") << " (__) \n" <<
+ OutputInDepth(depth, " ") << " (oo) \n" <<
+ OutputInDepth(depth, " ") << " /------\\/ \n" <<
+ OutputInDepth(depth, " ") << " / | || \n" <<
+ OutputInDepth(depth, " ") << " * /\\---/\\ \n" <<
+ OutputInDepth(depth, " ") << " ~~ ~~ \n" <<
+ moo;
+ return true;
+}
+ /*}}}*/
+bool DoMoo2(CommandLine &CmdL) /*{{{*/
+{
+ // by Fernando Ribeiro in lp:56125
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/4;
+ if (_config->FindB("APT::Moo::Color", false) == false)
+ c1out <<
+ OutputInDepth(depth, " ") << " (__) \n" <<
+ OutputInDepth(depth, " ") << " _______~(..)~ \n" <<
+ OutputInDepth(depth, " ") << " ,----\\(oo) \n" <<
+ OutputInDepth(depth, " ") << " /|____|,' \n" <<
+ OutputInDepth(depth, " ") << " * /\"\\ /\\ \n" <<
+ OutputInDepth(depth, " ") << " ~ ~ ~ ~ \n" <<
+ moo;
+ else
+ {
+ c1out <<
+ OutputInDepth(depth, " ") << " \e[1;97m(\e[0;33m__\e[1;97m)\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[31m_______\e[33m~(\e[1;34m..\e[0;33m)~\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[33m,----\e[31m\\\e[33m(\e[1;4;35moo\e[0;33m)\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[33m/|____|,'\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[1;5;97m*\e[0;33m /\\ /\\\e[0m\n" <<
+ "\e[32m";
+ for (size_t i = moo.length()/2; i > 1; --i)
+ c1out << "wW";
+
+ c1out << "w\e[0m\n" << moo;
+ }
+
+ return true;
+}
+ /*}}}*/
+bool DoMoo3(CommandLine &CmdL) /*{{{*/
+{
+ // by Robert Millan in deb:134156
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/16;
+ c1out <<
+ OutputInDepth(depth, " ") << " \\_/ \n" <<
+ OutputInDepth(depth, " ") << " m00h (__) -(_)- \n" <<
+ OutputInDepth(depth, " ") << " \\ ~Oo~___ / \\\n" <<
+ OutputInDepth(depth, " ") << " (..) |\\ \n" <<
+ OutputInDepth(depth, "_") << "_________|_|_|__________" <<
+ OutputInDepth((moo.length() - (depth + 27)), "_") << "\n" << moo;
+ return true;
+}
+ /*}}}*/
+bool DoMooApril(CommandLine &CmdL) /*{{{*/
+{
+ // by Christopher Allan Webber and proposed by Paul Tagliamonte
+ // in a "Community outreach": https://lists.debian.org/debian-devel/2013/04/msg00045.html
+ if (_config->FindI("quiet") >= 2)
+ {
+ std::cerr << "Have you smashed some milk today?" << std::endl;
+ return true;
+ }
+ c1out <<
+ " _ _\n"
+ " (_\\___( \\,\n"
+ " )___ _ Have you smashed some milk today?\n"
+ " /( (_)-(_) /\n"
+ " ,---------' \\_\n"
+ " //( ',__,' \\ (' ')\n"
+ " // ) '----'\n"
+ " '' ; \\ .--. ,/\n"
+ " | )',_,'----( ;\n"
+ " ||| ''' '||\n";
+ return true;
+}
+ /*}}}*/
+bool DoMoo(CommandLine &CmdL) /*{{{*/
+{
+ time_t const timenow = time(NULL);
+ struct tm april;
+ localtime_r(&timenow, &april);
+ if (april.tm_mday == 1 && april.tm_mon == 3)
+ return DoMooApril(CmdL);
+
+ signed short SuperCow = 1;
+ if (CmdL.FileSize() != 0)
+ for (const char **Moo = CmdL.FileList + 1; *Moo != 0; Moo++)
+ if (strcasecmp(*Moo, "moo") == 0)
+ SuperCow++;
+
+ // time is random enough for our purpose
+ if (SuperCow > 3)
+ {
+ if (april.tm_sec == 1)
+ SuperCow = 1 + (timenow % 4);
+ else
+ SuperCow = 1 + (timenow % 3);
+ }
+
+ switch(SuperCow) {
+ case 1: return DoMoo1(CmdL);
+ case 2: return DoMoo2(CmdL);
+ case 3: return DoMoo3(CmdL);
+ case 4: return DoMooApril(CmdL);
+ default: return DoMoo1(CmdL);
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-moo.h b/apt-private/private-moo.h
new file mode 100644
index 000000000..7bfc5c1fc
--- /dev/null
+++ b/apt-private/private-moo.h
@@ -0,0 +1,12 @@
+#ifndef APT_PRIVATE_MOO_H
+#define APT_PRIVATE_MOO_H
+
+class CommandLine;
+
+bool DoMoo(CommandLine &CmdL);
+bool DoMoo1(CommandLine &CmdL);
+bool DoMoo2(CommandLine &CmdL);
+bool DoMoo3(CommandLine &CmdL);
+bool DoMooApril(CommandLine &CmdL);
+
+#endif
diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc
new file mode 100644
index 000000000..659975476
--- /dev/null
+++ b/apt-private/private-output.cc
@@ -0,0 +1,753 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/policy.h>
+
+#include <iomanip>
+#include <iostream>
+#include <locale.h>
+#include <langinfo.h>
+#include <unistd.h>
+
+#include "private-output.h"
+#include "private-cachefile.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+std::ostream c0out(0);
+std::ostream c1out(0);
+std::ostream c2out(0);
+std::ofstream devnull("/dev/null");
+unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
+
+
+bool InitOutput()
+{
+ c0out.rdbuf(cout.rdbuf());
+ c1out.rdbuf(cout.rdbuf());
+ c2out.rdbuf(cout.rdbuf());
+ if (_config->FindI("quiet",0) > 0)
+ c0out.rdbuf(devnull.rdbuf());
+ if (_config->FindI("quiet",0) > 1)
+ c1out.rdbuf(devnull.rdbuf());
+
+ if(!isatty(1))
+ {
+ _config->Set("APT::Color", "false");
+ _config->Set("APT::Color::Highlight", "");
+ _config->Set("APT::Color::Neutral", "");
+ } else {
+ // Colors
+ _config->CndSet("APT::Color::Highlight", "\x1B[32m");
+ _config->CndSet("APT::Color::Neutral", "\x1B[0m");
+
+ _config->CndSet("APT::Color::Red", "\x1B[31m");
+ _config->CndSet("APT::Color::Green", "\x1B[32m");
+ _config->CndSet("APT::Color::Yellow", "\x1B[33m");
+ _config->CndSet("APT::Color::Blue", "\x1B[34m");
+ _config->CndSet("APT::Color::Magenta", "\x1B[35m");
+ _config->CndSet("APT::Color::Cyan", "\x1B[36m");
+ _config->CndSet("APT::Color::White", "\x1B[37m");
+ }
+
+ return true;
+}
+
+std::string GetArchiveSuite(pkgCacheFile &CacheFile, pkgCache::VerIterator ver)
+{
+ std::string suite = "";
+ if (ver && ver.FileList() && ver.FileList())
+ {
+ pkgCache::VerFileIterator VF = ver.FileList();
+ for (; VF.end() == false ; ++VF)
+ {
+ // XXX: how to figure out the relevant suite? if its in multiple ones?
+ suite = suite + "," + VF.File().Archive();
+ //suite = VF.File().Archive();
+ }
+ suite = suite.erase(0, 1);
+ }
+ return suite;
+}
+
+std::string GetFlagsStr(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+
+ std::string flags_str;
+ if (state.NowBroken())
+ flags_str = "B";
+ if (P.CurrentVer() && state.Upgradable())
+ flags_str = "g";
+ else if (P.CurrentVer() != NULL)
+ flags_str = "i";
+ else
+ flags_str = "-";
+ return flags_str;
+}
+
+std::string GetCandidateVersion(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ pkgCache::VerIterator cand = policy->GetCandidateVer(P);
+
+ return cand ? cand.VerStr() : "(none)";
+}
+
+std::string GetInstalledVersion(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgCache::VerIterator inst = P.CurrentVer();
+
+ return inst ? inst.VerStr() : "(none)";
+}
+
+std::string GetVersion(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
+{
+ pkgCache::PkgIterator P = V.ParentPkg();
+ if (V == P.CurrentVer())
+ {
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+ std::string inst_str = DeNull(V.VerStr());
+ if (state.Upgradable())
+ return "**"+inst_str;
+ return inst_str;
+ }
+
+ if(V)
+ return DeNull(V.VerStr());
+ return "(none)";
+}
+
+std::string GetArchitecture(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ pkgCache::VerIterator inst = P.CurrentVer();
+ pkgCache::VerIterator cand = policy->GetCandidateVer(P);
+
+ return inst ? inst.Arch() : cand.Arch();
+}
+
+std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+
+ pkgCache::VerIterator ver;
+ if (P.CurrentVer())
+ ver = P.CurrentVer();
+ else
+ ver = policy->GetCandidateVer(P);
+
+ std::string ShortDescription = "(none)";
+ if(ver)
+ {
+ pkgCache::DescIterator Desc = ver.TranslatedDescription();
+ pkgRecords::Parser & parser = records.Lookup(Desc.FileList());
+
+ ShortDescription = parser.ShortDesc();
+ }
+ return ShortDescription;
+}
+
+void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::VerIterator V, std::ostream &out)
+{
+ pkgCache::PkgIterator P = V.ParentPkg();
+
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+
+ std::string suite = GetArchiveSuite(CacheFile, V);
+ std::string name_str = P.Name();
+
+ if (_config->FindB("APT::Cmd::use-format", false))
+ {
+ std::string format = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}");
+ std::string output = format;
+
+ output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P));
+ output = SubstVar(output, "${Package}", name_str);
+ output = SubstVar(output, "${installed:Version}", GetInstalledVersion(CacheFile, P));
+ output = SubstVar(output, "${candidate:Version}", GetCandidateVersion(CacheFile, P));
+ output = SubstVar(output, "${Version}", GetVersion(CacheFile, V));
+ output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P));
+ output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V));
+ out << output << std::endl;
+ } else {
+ // raring/linux-kernel version [upradable: new-version]
+ // description
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ out << std::setiosflags(std::ios::left)
+ << _config->Find("APT::Color::Highlight", "")
+ << name_str
+ << _config->Find("APT::Color::Neutral", "")
+ << "/" << suite
+ << " ";
+ if(P.CurrentVer() == V && state.Upgradable()) {
+ out << GetVersion(CacheFile, V)
+ << " "
+ << "[" << _("installed,upgradable to: ")
+ << GetCandidateVersion(CacheFile, P) << "]";
+ } else if (P.CurrentVer() == V) {
+ out << GetVersion(CacheFile, V)
+ << " ";
+ if(!V.Downloadable())
+ out << _("[installed,local]");
+ else
+ if(V.Automatic() && state.Garbage)
+ out << _("[installed,auto-removable]");
+ else if (state.Flags & pkgCache::Flag::Auto)
+ out << _("[installed,automatic]");
+ else
+ out << _("[installed]");
+ } else if (P.CurrentVer() &&
+ policy->GetCandidateVer(P) == V &&
+ state.Upgradable()) {
+ out << GetVersion(CacheFile, V)
+ << " "
+ << _("[upgradable from: ")
+ << GetInstalledVersion(CacheFile, P) << "]";
+ } else {
+ if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles)
+ out << GetVersion(CacheFile, V)
+ << " "
+ << _("[residual-config]");
+ else
+ out << GetVersion(CacheFile, V);
+ }
+ out << " " << GetArchitecture(CacheFile, P) << " ";
+ out << std::endl
+ << " " << GetShortDescription(CacheFile, records, P)
+ << std::endl;
+ }
+}
+
+
+// ShowList - Show a list /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a string of space separated words with a title and
+ a two space indent line wraped to the current screen width. */
+bool ShowList(ostream &out,string Title,string List,string VersionsList)
+{
+ if (List.empty() == true)
+ return true;
+ // trim trailing space
+ int NonSpace = List.find_last_not_of(' ');
+ if (NonSpace != -1)
+ {
+ List = List.erase(NonSpace + 1);
+ if (List.empty() == true)
+ return true;
+ }
+
+ // Acount for the leading space
+ int ScreenWidth = ::ScreenWidth - 3;
+
+ out << Title << endl;
+ string::size_type Start = 0;
+ string::size_type VersionsStart = 0;
+ while (Start < List.size())
+ {
+ if(_config->FindB("APT::Get::Show-Versions",false) == true &&
+ VersionsList.size() > 0) {
+ string::size_type End;
+ string::size_type VersionsEnd;
+
+ End = List.find(' ',Start);
+ VersionsEnd = VersionsList.find('\n', VersionsStart);
+
+ out << " " << string(List,Start,End - Start) << " (" <<
+ string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
+ ")" << endl;
+
+ if (End == string::npos || End < Start)
+ End = Start + ScreenWidth;
+
+ Start = End + 1;
+ VersionsStart = VersionsEnd + 1;
+ } else {
+ string::size_type End;
+
+ if (Start + ScreenWidth >= List.size())
+ End = List.size();
+ else
+ End = List.rfind(' ',Start+ScreenWidth);
+
+ if (End == string::npos || End < Start)
+ End = Start + ScreenWidth;
+ out << " " << string(List,Start,End - Start) << endl;
+ Start = End + 1;
+ }
+ }
+
+ return false;
+}
+ /*}}}*/
+// ShowBroken - Debugging aide /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the names of all the packages that are broken along
+ with the name of each each broken dependency and a quite version
+ description.
+
+ The output looks like:
+ The following packages have unmet dependencies:
+ exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
+ Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
+ Depends: libsasl7 but it is not going to be installed
+ */
+void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
+{
+ if (Cache->BrokenCount() == 0)
+ return;
+
+ out << _("The following packages have unmet dependencies:") << endl;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ if (Now == true)
+ {
+ if (Cache[I].NowBroken() == false)
+ continue;
+ }
+ else
+ {
+ if (Cache[I].InstBroken() == false)
+ continue;
+ }
+
+ // Print out each package and the failed dependencies
+ out << " " << I.FullName(true) << " :";
+ unsigned const Indent = I.FullName(true).size() + 3;
+ bool First = true;
+ pkgCache::VerIterator Ver;
+
+ if (Now == true)
+ Ver = I.CurrentVer();
+ else
+ Ver = Cache[I].InstVerIter(Cache);
+
+ if (Ver.end() == true)
+ {
+ out << endl;
+ continue;
+ }
+
+ for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
+ {
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End); // advances D
+
+ if (Cache->IsImportantDep(End) == false)
+ continue;
+
+ if (Now == true)
+ {
+ if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
+ continue;
+ }
+ else
+ {
+ if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+ continue;
+ }
+
+ bool FirstOr = true;
+ while (1)
+ {
+ if (First == false)
+ for (unsigned J = 0; J != Indent; J++)
+ out << ' ';
+ First = false;
+
+ if (FirstOr == false)
+ {
+ for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
+ out << ' ';
+ }
+ else
+ out << ' ' << End.DepType() << ": ";
+ FirstOr = false;
+
+ out << Start.TargetPkg().FullName(true);
+
+ // Show a quick summary of the version requirements
+ if (Start.TargetVer() != 0)
+ out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
+
+ /* Show a summary of the target package if possible. In the case
+ of virtual packages we show nothing */
+ pkgCache::PkgIterator Targ = Start.TargetPkg();
+ if (Targ->ProvidesList == 0)
+ {
+ out << ' ';
+ pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
+ if (Now == true)
+ Ver = Targ.CurrentVer();
+
+ if (Ver.end() == false)
+ {
+ if (Now == true)
+ ioprintf(out,_("but %s is installed"),Ver.VerStr());
+ else
+ ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
+ }
+ else
+ {
+ if (Cache[Targ].CandidateVerIter(Cache).end() == true)
+ {
+ if (Targ->ProvidesList == 0)
+ out << _("but it is not installable");
+ else
+ out << _("but it is a virtual package");
+ }
+ else
+ out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
+ }
+ }
+
+ if (Start != End)
+ out << _(" or");
+ out << endl;
+
+ if (Start == End)
+ break;
+ ++Start;
+ }
+ }
+ }
+}
+ /*}}}*/
+// ShowNew - Show packages to newly install /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowNew(ostream &out,CacheFile &Cache)
+{
+ /* Print out a list of packages that are going to be installed extra
+ to what the user asked */
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].NewInstall() == true) {
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CandVersion) + "\n";
+ }
+ }
+
+ ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowDel - Show packages to delete /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowDel(ostream &out,CacheFile &Cache)
+{
+ /* Print out a list of packages that are going to be removed extra
+ to what the user asked */
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].Delete() == true)
+ {
+ if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ List += I.FullName(true) + "* ";
+ else
+ List += I.FullName(true) + " ";
+
+ VersionsList += string(Cache[I].CandVersion)+ "\n";
+ }
+ }
+
+ ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowKept - Show kept packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowKept(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
+ I->CurrentVer == 0 || Cache[I].Delete() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowUpgraded - Show upgraded packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowUpgraded(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowDowngraded - Show downgraded packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowDowngraded(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowHold - Show held but changed packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHold(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
+ I->SelectedState == pkgCache::State::Hold) {
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ }
+
+ return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowEssential - Show an essential package warning /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a warning message that is not to be ignored. It shows
+ all essential packages and their dependents that are to be removed.
+ It is insanely risky to remove the dependents of an essential package! */
+bool ShowEssential(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ bool *Added = new bool[Cache->Head().PackageCount];
+ for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
+ Added[I] = false;
+
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
+ (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
+ continue;
+
+ // The essential package is being removed
+ if (Cache[I].Delete() == true)
+ {
+ if (Added[I->ID] == false)
+ {
+ Added[I->ID] = true;
+ List += I.FullName(true) + " ";
+ //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
+ }
+ }
+ else
+ continue;
+
+ if (I->CurrentVer == 0)
+ continue;
+
+ // Print out any essential package depenendents that are to be removed
+ for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; ++D)
+ {
+ // Skip everything but depends
+ if (D->Type != pkgCache::Dep::PreDepends &&
+ D->Type != pkgCache::Dep::Depends)
+ continue;
+
+ pkgCache::PkgIterator P = D.SmartTargetPkg();
+ if (Cache[P].Delete() == true)
+ {
+ if (Added[P->ID] == true)
+ continue;
+ Added[P->ID] = true;
+
+ char S[300];
+ snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
+ List += S;
+ //VersionsList += "\n"; ???
+ }
+ }
+ }
+
+ delete [] Added;
+ return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
+ "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
+}
+
+ /*}}}*/
+// Stats - Show some statistics /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Stats(ostream &out,pkgDepCache &Dep)
+{
+ unsigned long Upgrade = 0;
+ unsigned long Downgrade = 0;
+ unsigned long Install = 0;
+ unsigned long ReInstall = 0;
+ for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; ++I)
+ {
+ if (Dep[I].NewInstall() == true)
+ Install++;
+ else
+ {
+ if (Dep[I].Upgrade() == true)
+ Upgrade++;
+ else
+ if (Dep[I].Downgrade() == true)
+ Downgrade++;
+ }
+
+ if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
+ ReInstall++;
+ }
+
+ ioprintf(out,_("%lu upgraded, %lu newly installed, "),
+ Upgrade,Install);
+
+ if (ReInstall != 0)
+ ioprintf(out,_("%lu reinstalled, "),ReInstall);
+ if (Downgrade != 0)
+ ioprintf(out,_("%lu downgraded, "),Downgrade);
+
+ ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
+ Dep.DelCount(),Dep.KeepCount());
+
+ if (Dep.BadCount() != 0)
+ ioprintf(out,_("%lu not fully installed or removed.\n"),
+ Dep.BadCount());
+}
+ /*}}}*/
+// YnPrompt - Yes No Prompt. /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool YnPrompt(bool Default)
+{
+ /* nl_langinfo does not support LANGUAGE setting, so we unset it here
+ to have the help-message (hopefully) match the expected characters */
+ char * language = getenv("LANGUAGE");
+ if (language != NULL)
+ language = strdup(language);
+ if (language != NULL)
+ unsetenv("LANGUAGE");
+
+ if (Default == true)
+ // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
+ // e.g. "Do you want to continue? [Y/n] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[Y/n]") << " " << std::flush;
+ else
+ // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
+ // e.g. "Should this file be removed? [y/N] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[y/N]") << " " << std::flush;
+
+ if (language != NULL)
+ {
+ setenv("LANGUAGE", language, 0);
+ free(language);
+ }
+
+ if (_config->FindB("APT::Get::Assume-Yes",false) == true)
+ {
+ // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
+ c1out << _("Y") << std::endl;
+ return true;
+ }
+ else if (_config->FindB("APT::Get::Assume-No",false) == true)
+ {
+ // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
+ c1out << _("N") << std::endl;
+ return false;
+ }
+
+ char response[1024] = "";
+ std::cin.getline(response, sizeof(response));
+
+ if (!std::cin)
+ return false;
+
+ if (strlen(response) == 0)
+ return Default;
+
+ regex_t Pattern;
+ int Res;
+
+ Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
+ REG_EXTENDED|REG_ICASE|REG_NOSUB);
+
+ if (Res != 0) {
+ char Error[300];
+ regerror(Res,&Pattern,Error,sizeof(Error));
+ return _error->Error(_("Regex compilation error - %s"),Error);
+ }
+
+ Res = regexec(&Pattern, response, 0, NULL, 0);
+ if (Res == 0)
+ return true;
+ return false;
+}
+ /*}}}*/
+// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool AnalPrompt(const char *Text)
+{
+ char Buf[1024];
+ std::cin.getline(Buf,sizeof(Buf));
+ if (strcmp(Buf,Text) == 0)
+ return true;
+ return false;
+}
+ /*}}}*/
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
new file mode 100644
index 000000000..9283e39ab
--- /dev/null
+++ b/apt-private/private-output.h
@@ -0,0 +1,49 @@
+#ifndef APT_PRIVATE_OUTPUT_H
+#define APT_PRIVATE_OUTPUT_H
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "private-cachefile.h"
+
+// forward declaration
+class pkgCacheFile;
+class CacheFile;
+class pkgCache;
+class pkgDepCache;
+class pkgRecords;
+
+
+extern std::ostream c0out;
+extern std::ostream c1out;
+extern std::ostream c2out;
+extern std::ofstream devnull;
+extern unsigned int ScreenWidth;
+
+bool InitOutput();
+void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::VerIterator V, std::ostream &out);
+
+
+
+bool ShowList(std::ostream &out, std::string Title, std::string List,
+ std::string VersionsList);
+void ShowBroken(std::ostream &out,CacheFile &Cache,bool Now);
+void ShowNew(std::ostream &out,CacheFile &Cache);
+void ShowDel(std::ostream &out,CacheFile &Cache);
+void ShowKept(std::ostream &out,CacheFile &Cache);
+void ShowUpgraded(std::ostream &out,CacheFile &Cache);
+bool ShowDowngraded(std::ostream &out,CacheFile &Cache);
+bool ShowHold(std::ostream &out,CacheFile &Cache);
+
+bool ShowEssential(std::ostream &out,CacheFile &Cache);
+
+void Stats(std::ostream &out, pkgDepCache &Dep);
+
+// prompting
+bool YnPrompt(bool Default=true);
+bool AnalPrompt(const char *Text);
+
+#endif
diff --git a/apt-private/private-search.cc b/apt-private/private-search.cc
new file mode 100644
index 000000000..6881f482f
--- /dev/null
+++ b/apt-private/private-search.cc
@@ -0,0 +1,99 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <sstream>
+#include <utility>
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <iomanip>
+#include <algorithm>
+#include <map>
+
+#include "private-search.h"
+#include "private-cacheset.h"
+
+
+bool FullTextSearch(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache::Policy *Plcy = CacheFile.GetPolicy();
+ pkgRecords records(CacheFile);
+ if (unlikely(Cache == NULL || Plcy == NULL))
+ return false;
+
+ const char **patterns;
+ patterns = CmdL.FileList + 1;
+
+ std::map<std::string, std::string> output_map;
+ std::map<std::string, std::string>::const_iterator K;
+
+ LocalitySortedVersionSet bag;
+ OpTextProgress progress;
+ progress.OverallProgress(0, 100, 50, _("Sorting"));
+ GetLocalitySortedVersionSet(CacheFile, bag, progress);
+ LocalitySortedVersionSet::iterator V = bag.begin();
+
+ progress.OverallProgress(50, 100, 50, _("Full Text Search"));
+ progress.SubProgress(bag.size());
+ int Done = 0;
+ for ( ;V != bag.end(); V++)
+ {
+ if (Done%500 == 0)
+ progress.Progress(Done);
+ Done++;
+
+ int i;
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ pkgRecords::Parser &parser = records.Lookup(Desc.FileList());
+
+ bool all_found = true;
+ for(i=0; patterns[i] != NULL; i++)
+ {
+ // FIXME: use regexp instead of simple find()
+ const char *pattern = patterns[i];
+ all_found &= (
+ strstr(V.ParentPkg().Name(), pattern) != NULL ||
+ parser.ShortDesc().find(pattern) != std::string::npos ||
+ parser.LongDesc().find(pattern) != std::string::npos);
+ }
+ if (all_found)
+ {
+ std::stringstream outs;
+ ListSingleVersion(CacheFile, records, V, outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ }
+ }
+ progress.Done();
+
+ // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
+ // output the sorted map
+ for (K = output_map.begin(); K != output_map.end(); K++)
+ std::cout << (*K).second << std::endl;
+
+ return true;
+}
diff --git a/apt-private/private-search.h b/apt-private/private-search.h
new file mode 100644
index 000000000..17faffebc
--- /dev/null
+++ b/apt-private/private-search.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_SEARCH_H
+#define APT_PRIVATE_SEARCH_H
+
+#include <apt-pkg/cmndline.h>
+
+bool FullTextSearch(CommandLine &CmdL);
+
+
+#endif
diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc
new file mode 100644
index 000000000..e26a2b30a
--- /dev/null
+++ b/apt-private/private-show.cc
@@ -0,0 +1,122 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <apti18n.h>
+
+#include "private-output.h"
+#include "private-cacheset.h"
+
+namespace APT {
+ namespace Cmd {
+
+// DisplayRecord - Displays the complete record for the package /*{{{*/
+// ---------------------------------------------------------------------
+bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V,
+ ostream &out)
+{
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ // Find an appropriate file
+ pkgCache::VerFileIterator Vf = V.FileList();
+ for (; Vf.end() == false; ++Vf)
+ if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
+ break;
+ if (Vf.end() == true)
+ Vf = V.FileList();
+
+ // Check and load the package list file
+ pkgCache::PkgFileIterator I = Vf.File();
+ if (I.IsOk() == false)
+ return _error->Error(_("Package file %s is out of sync."),I.FileName());
+
+ // Read the record
+ FileFd PkgF;
+ if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
+ return false;
+ pkgTagSection Tags;
+ pkgTagFile TagF(&PkgF);
+
+ TFRewriteData RW[] = {
+ {"Conffiles",0},
+ {"Description",0},
+ {"Description-md5",0},
+ {}
+ };
+ const char *Zero = 0;
+ if (TagF.Jump(Tags, V.FileList()->Offset) == false ||
+ TFRewrite(stdout,Tags,&Zero,RW) == false)
+ {
+ _error->Error("Internal Error, Unable to parse a package record");
+ return false;
+ }
+
+ // write the description
+ pkgRecords Recs(*Cache);
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ if (Desc.end() == false)
+ {
+ pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+ if (strcmp(Desc.LanguageCode(),"") != 0)
+ out << "Description-lang: " << Desc.LanguageCode() << std::endl;
+ out << "Description" << P.LongDesc();
+ }
+
+ // write a final newline (after the description)
+ out << std::endl << std::endl;
+
+ return true;
+}
+ /*}}}*/
+
+bool ShowPackage(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
+ APT::VersionList::Version const select = APT::VersionList::CANDIDATE;
+ APT::VersionList const verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper);
+ for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver)
+ if (DisplayRecord(CacheFile, Ver, c1out) == false)
+ return false;
+
+ for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
+ Pkg != helper.virtualPkgs.end(); ++Pkg)
+ {
+ c1out << "Package: " << Pkg.FullName(true) << std::endl;
+ c1out << "State: " << _("not a real pacakge (virtual)") << std::endl;
+ // FIXME: show providers, see private-cacheset.h
+ // CacheSetHelperAPTGet::showVirtualPackageErrors()
+ }
+
+ if (verset.empty() == true)
+ {
+ if (helper.virtualPkgs.empty() == true)
+ return _error->Error(_("No packages found"));
+ else
+ _error->Notice(_("No packages found"));
+ }
+
+ return true;
+}
+ /*}}}*/
+} // namespace Cmd
+} // namespace APT
diff --git a/apt-private/private-show.h b/apt-private/private-show.h
new file mode 100644
index 000000000..b428c7af0
--- /dev/null
+++ b/apt-private/private-show.h
@@ -0,0 +1,12 @@
+#ifndef APT_PRIVATE_SHOW_H
+#define APT_PRIVATE_SHOW_H
+
+#include <apt-pkg/cmndline.h>
+
+namespace APT {
+ namespace Cmd {
+
+ bool ShowPackage(CommandLine &CmdL);
+ }
+}
+#endif
diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc
new file mode 100644
index 000000000..61259748d
--- /dev/null
+++ b/apt-private/private-update.cc
@@ -0,0 +1,93 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/versionmatch.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "private-cachefile.h"
+#include "private-output.h"
+#include "acqprogress.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+// DoUpdate - Update the package lists /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoUpdate(CommandLine &CmdL)
+{
+ if (CmdL.FileSize() != 1)
+ return _error->Error(_("The update command takes no arguments"));
+
+ CacheFile Cache;
+
+ // Get the source list
+ if (Cache.BuildSourceList() == false)
+ return false;
+ pkgSourceList *List = Cache.GetSourceList();
+
+ // Create the progress
+ AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+
+ // Just print out the uris an exit if the --print-uris flag was used
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ // force a hashsum for compatibility reasons
+ _config->CndSet("Acquire::ForceHash", "md5sum");
+
+ // get a fetcher
+ pkgAcquire Fetcher;
+ if (Fetcher.Setup(&Stat) == false)
+ return false;
+
+ // Populate it with the source selection and get all Indexes
+ // (GetAll=true)
+ if (List->GetIndexes(&Fetcher,true) == false)
+ return false;
+
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); ++I)
+ c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
+ return true;
+ }
+
+ // do the work
+ if (_config->FindB("APT::Get::Download",true) == true)
+ ListUpdate(Stat, *List);
+
+ // Rebuild the cache.
+ if (_config->FindB("pkgCacheFile::Generate", true) == true)
+ {
+ pkgCacheFile::RemoveCaches();
+ if (Cache.BuildCaches() == false)
+ return false;
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-update.h b/apt-private/private-update.h
new file mode 100644
index 000000000..d3d0b7af9
--- /dev/null
+++ b/apt-private/private-update.h
@@ -0,0 +1,8 @@
+#ifndef APT_PRIVATE_UPDATE_H
+#define APT_PRIVATE_UPDATE_H
+
+class CommandLine;
+
+bool DoUpdate(CommandLine &CmdL);
+
+#endif
diff --git a/apt-private/private-upgrade.cc b/apt-private/private-upgrade.cc
new file mode 100644
index 000000000..eb546e3e3
--- /dev/null
+++ b/apt-private/private-upgrade.cc
@@ -0,0 +1,53 @@
+
+#include <apt-pkg/algorithms.h>
+
+#include "private-install.h"
+#include "private-cachefile.h"
+#include "private-upgrade.h"
+#include "private-output.h"
+
+
+// DoUpgradeNoNewPackages - Upgrade all packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Upgrade all packages without installing new packages or erasing old
+ packages */
+bool DoUpgradeNoNewPackages(CommandLine &CmdL)
+{
+ if (CmdL.FileSize() != 1)
+ return _error->Error(_("The upgrade command takes no arguments"));
+
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+ return false;
+
+ // Do the upgrade
+ if (pkgAllUpgrade(Cache) == false)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, AllUpgrade broke stuff"));
+ }
+
+ return InstallPackages(Cache,true);
+}
+ /*}}}*/
+
+// DoSafeUpgrade - Upgrade all packages with install but not remove /*{{{*/
+bool DoUpgradeWithAllowNewPackages(CommandLine &CmdL)
+{
+ if (CmdL.FileSize() != 1)
+ return _error->Error(_("The upgrade command takes no arguments"));
+
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+ return false;
+
+ // Do the upgrade
+ if (pkgAllUpgradeNoDelete(Cache) == false)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, AllUpgrade broke stuff"));
+ }
+
+ return InstallPackages(Cache,true);
+}
+ /*}}}*/
diff --git a/apt-private/private-upgrade.h b/apt-private/private-upgrade.h
new file mode 100644
index 000000000..6ede6f96c
--- /dev/null
+++ b/apt-private/private-upgrade.h
@@ -0,0 +1,11 @@
+#ifndef APTPRIVATE_PRIVATE_UPGRADE_H
+#define APTPRIVATE_PRIVATE_UPGRADE_H
+
+#include <apt-pkg/cmndline.h>
+
+
+bool DoUpgradeNoNewPackages(CommandLine &CmdL);
+bool DoUpgradeWithAllowNewPackages(CommandLine &CmdL);
+
+
+#endif
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index e847de875..b8892d23d 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -35,6 +35,11 @@
#include <apt-pkg/indexfile.h>
#include <apt-pkg/metaindex.h>
+#include <apt-private/private-list.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-show.h>
+#include <apt-private/private-cacheset.h>
+
#include <cassert>
#include <locale.h>
#include <iostream>
@@ -50,29 +55,6 @@
using namespace std;
-// CacheSetHelper saving virtual packages /*{{{*/
-class CacheSetHelperVirtuals: public APT::CacheSetHelper {
-public:
- APT::PackageSet virtualPkgs;
-
- virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- return CacheSetHelper::canNotFindCandidateVer(Cache, Pkg);
- }
-
- virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- return CacheSetHelper::canNotFindNewestVer(Cache, Pkg);
- }
-
- virtual void canNotFindAllVer(APT::VersionContainerInterface * vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- CacheSetHelper::canNotFindAllVer(vci, Cache, Pkg);
- }
-
- CacheSetHelperVirtuals(bool const ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {}
-};
- /*}}}*/
// LocalitySort - Sort a version list by package file locality /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -396,42 +378,42 @@ bool Dump(CommandLine &Cmd)
if (unlikely(Cache == NULL))
return false;
- cout << "Using Versioning System: " << Cache->VS->Label << endl;
+ std::cout << "Using Versioning System: " << Cache->VS->Label << std::endl;
for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
{
- cout << "Package: " << P.FullName(true) << endl;
+ std::cout << "Package: " << P.FullName(true) << std::endl;
for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
{
- cout << " Version: " << V.VerStr() << endl;
- cout << " File: " << V.FileList().File().FileName() << endl;
+ std::cout << " Version: " << V.VerStr() << std::endl;
+ std::cout << " File: " << V.FileList().File().FileName() << std::endl;
for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
- cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
- DeNull(D.TargetVer()) << endl;
+ std::cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
+ DeNull(D.TargetVer()) << std::endl;
for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
{
- cout << " Description Language: " << D.LanguageCode() << endl
- << " File: " << D.FileList().File().FileName() << endl
- << " MD5: " << D.md5() << endl;
+ std::cout << " Description Language: " << D.LanguageCode() << std::endl
+ << " File: " << D.FileList().File().FileName() << std::endl
+ << " MD5: " << D.md5() << std::endl;
}
}
}
for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F)
{
- cout << "File: " << F.FileName() << endl;
- cout << " Type: " << F.IndexType() << endl;
- cout << " Size: " << F->Size << endl;
- cout << " ID: " << F->ID << endl;
- cout << " Flags: " << F->Flags << endl;
- cout << " Time: " << TimeRFC1123(F->mtime) << endl;
- cout << " Archive: " << DeNull(F.Archive()) << endl;
- cout << " Component: " << DeNull(F.Component()) << endl;
- cout << " Version: " << DeNull(F.Version()) << endl;
- cout << " Origin: " << DeNull(F.Origin()) << endl;
- cout << " Site: " << DeNull(F.Site()) << endl;
- cout << " Label: " << DeNull(F.Label()) << endl;
- cout << " Architecture: " << DeNull(F.Architecture()) << endl;
+ std::cout << "File: " << F.FileName() << std::endl;
+ std::cout << " Type: " << F.IndexType() << std::endl;
+ std::cout << " Size: " << F->Size << std::endl;
+ std::cout << " ID: " << F->ID << std::endl;
+ std::cout << " Flags: " << F->Flags << std::endl;
+ std::cout << " Time: " << TimeRFC1123(F->mtime) << std::endl;
+ std::cout << " Archive: " << DeNull(F.Archive()) << std::endl;
+ std::cout << " Component: " << DeNull(F.Component()) << std::endl;
+ std::cout << " Version: " << DeNull(F.Version()) << std::endl;
+ std::cout << " Origin: " << DeNull(F.Origin()) << std::endl;
+ std::cout << " Site: " << DeNull(F.Site()) << std::endl;
+ std::cout << " Label: " << DeNull(F.Label()) << std::endl;
+ std::cout << " Architecture: " << DeNull(F.Architecture()) << std::endl;
}
return true;
@@ -627,8 +609,7 @@ bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
case pkgCache::Dep::Depends: if (!ShowDepends) continue; break;
case pkgCache::Dep::Recommends: if (!ShowRecommends) continue; break;
case pkgCache::Dep::Suggests: if (!ShowSuggests) continue; break;
- case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break;
- case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
+ case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break; case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break;
case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break;
}
@@ -1238,7 +1219,6 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
return true;
}
/*}}}*/
-
struct ExDescFile
{
pkgCache::DescFile *Df;
@@ -1795,38 +1775,10 @@ bool ShowHelp(CommandLine &Cmd)
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
- {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
- {'q',"quiet","quiet",CommandLine::IntLevel},
- {'i',"important","APT::Cache::Important",0},
- {'f',"full","APT::Cache::ShowFull",0},
- {'g',"generate","APT::Cache::Generate",0},
- {'a',"all-versions","APT::Cache::AllVersions",0},
- {'n',"names-only","APT::Cache::NamesOnly",0},
- {0,"all-names","APT::Cache::AllNames",0},
- {0,"recurse","APT::Cache::RecurseDepends",0},
- {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
- {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,"installed","APT::Cache::Installed",0},
- {0,"pre-depends","APT::Cache::ShowPre-Depends",0},
- {0,"depends","APT::Cache::ShowDepends",0},
- {0,"recommends","APT::Cache::ShowRecommends",0},
- {0,"suggests","APT::Cache::ShowSuggests",0},
- {0,"replaces","APT::Cache::ShowReplaces",0},
- {0,"breaks","APT::Cache::ShowBreaks",0},
- {0,"conflicts","APT::Cache::ShowConflicts",0},
- {0,"enhances","APT::Cache::ShowEnhances",0},
- {0,0,0,0}};
- CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
+ CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
{"gencaches",&GenCaches},
{"showsrc",&ShowSrcPackage},
- {0,0}};
- CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
+ {"showpkg",&DumpPackage},
{"stats",&Stats},
{"dump",&Dump},
{"dumpavail",&DumpAvail},
@@ -1843,12 +1795,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"madison",&Madison},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cache", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -1872,8 +1826,8 @@ int main(int argc,const char *argv[]) /*{{{*/
if (_config->Exists("APT::Cache::Generate") == true)
_config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
- if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
- CmdL.DispatchArg(CmdsB);
+ // Match the operation
+ CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
bool const Errors = _error->PendingError();
diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc
index c153cca85..17a60ddcb 100644
--- a/cmdline/apt-cdrom.cc
+++ b/cmdline/apt-cdrom.cc
@@ -37,6 +37,8 @@
#include <unistd.h>
#include <stdio.h>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
static const char *W_NO_CDROM_FOUND = \
@@ -66,7 +68,9 @@ void pkgCdromTextStatus::Prompt(const char *Text)
{
char C;
cout << Text << ' ' << flush;
- read(STDIN_FILENO,&C,1);
+ if (read(STDIN_FILENO,&C,1) < 0)
+ _error->Errno("pkgCdromTextStatus::Prompt",
+ "Failed to read from standard input (not a terminal?)");
if (C != '\n')
cout << endl;
}
@@ -201,12 +205,12 @@ bool DoIdent(CommandLine &)
// ShowHelp - Show the help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
-int ShowHelp()
+bool ShowHelp(CommandLine &)
{
ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
COMMON_ARCH,__DATE__,__TIME__);
if (_config->FindB("version") == true)
- return 0;
+ return true;
cout <<
"Usage: apt-cdrom [options] command\n"
@@ -230,37 +234,25 @@ int ShowHelp()
" -c=? Read this configuration file\n"
" -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
"See fstab(5)\n";
- return 0;
+ return true;
}
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- { 0,"auto-detect","Acquire::cdrom::AutoDetect", CommandLine::Boolean},
- {'v',"version","version",0},
- {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
- {'r',"rename","APT::CDROM::Rename",0},
- {'m',"no-mount","APT::CDROM::NoMount",0},
- {'f',"fast","APT::CDROM::Fast",0},
- {'n',"just-print","APT::CDROM::NoAct",0},
- {'n',"recon","APT::CDROM::NoAct",0},
- {'n',"no-act","APT::CDROM::NoAct",0},
- {'a',"thorough","APT::CDROM::Thorough",0},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {
{"add",&DoAdd},
{"ident",&DoIdent},
+ {"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -272,7 +264,7 @@ int main(int argc,const char *argv[]) /*{{{*/
// See if the help should be shown
if (_config->FindB("help") == true || _config->FindB("version") == true ||
CmdL.FileSize() == 0)
- return ShowHelp();
+ return ShowHelp(CmdL);
// Deal with stdout not being a tty
if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc
index 397ce32df..3481eaf5f 100644
--- a/cmdline/apt-config.cc
+++ b/cmdline/apt-config.cc
@@ -31,6 +31,8 @@
#include <string>
#include <vector>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
using namespace std;
@@ -76,12 +78,12 @@ bool DoDump(CommandLine &CmdL)
// ShowHelp - Show the help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
-int ShowHelp()
+bool ShowHelp(CommandLine &CmdL)
{
ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
COMMON_ARCH,__DATE__,__TIME__);
if (_config->FindB("version") == true)
- return 0;
+ return true;
cout <<
_("Usage: apt-config [options] command\n"
@@ -96,29 +98,24 @@ int ShowHelp()
" -h This help text.\n"
" -c=? Read this configuration file\n"
" -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
- return 0;
+ return true;
}
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean},
- {0,"format","APT::Config::Dump::Format",CommandLine::HasArg},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
{"dump",&DoDump},
+ {"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -130,7 +127,7 @@ int main(int argc,const char *argv[]) /*{{{*/
// See if the help should be shown
if (_config->FindB("help") == true ||
CmdL.FileSize() == 0)
- return ShowHelp();
+ return ShowHelp(CmdL);
std::vector<std::string> const langs = APT::Configuration::getLanguages(true);
_config->Clear("Acquire::Languages");
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 4b7691d93..93c21651f 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -50,7 +50,16 @@
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/indexfile.h>
-#include "acqprogress.h"
+
+#include <apt-private/private-install.h>
+#include <apt-private/private-upgrade.h>
+#include <apt-private/private-output.h>
+#include <apt-private/private-cacheset.h>
+#include <apt-private/private-update.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-moo.h>
+
+#include <apt-private/acqprogress.h>
#include <set>
#include <locale.h>
@@ -69,1391 +78,17 @@
#include <sys/wait.h>
#include <sstream>
+#include <apt-private/private-output.h>
+#include <apt-private/private-main.h>
+
#include <apti18n.h>
/*}}}*/
-#define RAMFS_MAGIC 0x858458f6
using namespace std;
-ostream c0out(0);
-ostream c1out(0);
-ostream c2out(0);
-ofstream devnull("/dev/null");
-unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
-
-// class CacheFile - Cover class for some dependency cache functions /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-class CacheFile : public pkgCacheFile
-{
- static pkgCache *SortCache;
- static int NameComp(const void *a,const void *b);
-
- public:
- pkgCache::Package **List;
-
- void Sort();
- bool CheckDeps(bool AllowBroken = false);
- bool BuildCaches(bool WithLock = true)
- {
- OpTextProgress Prog(*_config);
- if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false)
- return false;
- return true;
- }
- bool Open(bool WithLock = true)
- {
- OpTextProgress Prog(*_config);
- if (pkgCacheFile::Open(&Prog,WithLock) == false)
- return false;
- Sort();
-
- return true;
- };
- bool OpenForInstall()
- {
- if (_config->FindB("APT::Get::Print-URIs") == true)
- return Open(false);
- else
- return Open(true);
- }
- CacheFile() : List(0) {};
- ~CacheFile() {
- delete[] List;
- }
-};
- /*}}}*/
-
-// YnPrompt - Yes No Prompt. /*{{{*/
-// ---------------------------------------------------------------------
-/* Returns true on a Yes.*/
-bool YnPrompt(bool Default=true)
-{
- /* nl_langinfo does not support LANGUAGE setting, so we unset it here
- to have the help-message (hopefully) match the expected characters */
- char * language = getenv("LANGUAGE");
- if (language != NULL)
- language = strdup(language);
- if (language != NULL)
- unsetenv("LANGUAGE");
-
- if (Default == true)
- // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
- // e.g. "Do you want to continue? [Y/n] "
- // The user has to answer with an input matching the
- // YESEXPR/NOEXPR defined in your l10n.
- c2out << " " << _("[Y/n]") << " " << std::flush;
- else
- // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
- // e.g. "Should this file be removed? [y/N] "
- // The user has to answer with an input matching the
- // YESEXPR/NOEXPR defined in your l10n.
- c2out << " " << _("[y/N]") << " " << std::flush;
-
- if (language != NULL)
- {
- setenv("LANGUAGE", language, 0);
- free(language);
- }
-
- if (_config->FindB("APT::Get::Assume-Yes",false) == true)
- {
- // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
- c1out << _("Y") << endl;
- return true;
- }
- else if (_config->FindB("APT::Get::Assume-No",false) == true)
- {
- // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
- c1out << _("N") << endl;
- return false;
- }
-
- char response[1024] = "";
- cin.getline(response, sizeof(response));
-
- if (!cin)
- return false;
-
- if (strlen(response) == 0)
- return Default;
-
- regex_t Pattern;
- int Res;
-
- Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
- REG_EXTENDED|REG_ICASE|REG_NOSUB);
-
- if (Res != 0) {
- char Error[300];
- regerror(Res,&Pattern,Error,sizeof(Error));
- return _error->Error(_("Regex compilation error - %s"),Error);
- }
-
- Res = regexec(&Pattern, response, 0, NULL, 0);
- if (Res == 0)
- return true;
- return false;
-}
- /*}}}*/
-// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
-// ---------------------------------------------------------------------
-/* Returns true on a Yes.*/
-bool AnalPrompt(const char *Text)
-{
- char Buf[1024];
- cin.getline(Buf,sizeof(Buf));
- if (strcmp(Buf,Text) == 0)
- return true;
- return false;
-}
- /*}}}*/
-// ShowList - Show a list /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out a string of space separated words with a title and
- a two space indent line wraped to the current screen width. */
-bool ShowList(ostream &out,string Title,string List,string VersionsList)
-{
- if (List.empty() == true)
- return true;
- // trim trailing space
- int NonSpace = List.find_last_not_of(' ');
- if (NonSpace != -1)
- {
- List = List.erase(NonSpace + 1);
- if (List.empty() == true)
- return true;
- }
-
- // Acount for the leading space
- int ScreenWidth = ::ScreenWidth - 3;
-
- out << Title << endl;
- string::size_type Start = 0;
- string::size_type VersionsStart = 0;
- while (Start < List.size())
- {
- if(_config->FindB("APT::Get::Show-Versions",false) == true &&
- VersionsList.size() > 0) {
- string::size_type End;
- string::size_type VersionsEnd;
-
- End = List.find(' ',Start);
- VersionsEnd = VersionsList.find('\n', VersionsStart);
-
- out << " " << string(List,Start,End - Start) << " (" <<
- string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
- ")" << endl;
-
- if (End == string::npos || End < Start)
- End = Start + ScreenWidth;
-
- Start = End + 1;
- VersionsStart = VersionsEnd + 1;
- } else {
- string::size_type End;
-
- if (Start + ScreenWidth >= List.size())
- End = List.size();
- else
- End = List.rfind(' ',Start+ScreenWidth);
-
- if (End == string::npos || End < Start)
- End = Start + ScreenWidth;
- out << " " << string(List,Start,End - Start) << endl;
- Start = End + 1;
- }
- }
-
- return false;
-}
- /*}}}*/
-// ShowBroken - Debugging aide /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out the names of all the packages that are broken along
- with the name of each each broken dependency and a quite version
- description.
-
- The output looks like:
- The following packages have unmet dependencies:
- exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
- Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
- Depends: libsasl7 but it is not going to be installed
- */
-void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
-{
- if (Cache->BrokenCount() == 0)
- return;
-
- out << _("The following packages have unmet dependencies:") << endl;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- if (Now == true)
- {
- if (Cache[I].NowBroken() == false)
- continue;
- }
- else
- {
- if (Cache[I].InstBroken() == false)
- continue;
- }
-
- // Print out each package and the failed dependencies
- out << " " << I.FullName(true) << " :";
- unsigned const Indent = I.FullName(true).size() + 3;
- bool First = true;
- pkgCache::VerIterator Ver;
-
- if (Now == true)
- Ver = I.CurrentVer();
- else
- Ver = Cache[I].InstVerIter(Cache);
-
- if (Ver.end() == true)
- {
- out << endl;
- continue;
- }
-
- for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
- {
- // Compute a single dependency element (glob or)
- pkgCache::DepIterator Start;
- pkgCache::DepIterator End;
- D.GlobOr(Start,End); // advances D
-
- if (Cache->IsImportantDep(End) == false)
- continue;
-
- if (Now == true)
- {
- if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
- continue;
- }
- else
- {
- if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
- continue;
- }
-
- bool FirstOr = true;
- while (1)
- {
- if (First == false)
- for (unsigned J = 0; J != Indent; J++)
- out << ' ';
- First = false;
-
- if (FirstOr == false)
- {
- for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
- out << ' ';
- }
- else
- out << ' ' << End.DepType() << ": ";
- FirstOr = false;
-
- out << Start.TargetPkg().FullName(true);
-
- // Show a quick summary of the version requirements
- if (Start.TargetVer() != 0)
- out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
-
- /* Show a summary of the target package if possible. In the case
- of virtual packages we show nothing */
- pkgCache::PkgIterator Targ = Start.TargetPkg();
- if (Targ->ProvidesList == 0)
- {
- out << ' ';
- pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
- if (Now == true)
- Ver = Targ.CurrentVer();
-
- if (Ver.end() == false)
- {
- if (Now == true)
- ioprintf(out,_("but %s is installed"),Ver.VerStr());
- else
- ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
- }
- else
- {
- if (Cache[Targ].CandidateVerIter(Cache).end() == true)
- {
- if (Targ->ProvidesList == 0)
- out << _("but it is not installable");
- else
- out << _("but it is a virtual package");
- }
- else
- out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
- }
- }
-
- if (Start != End)
- out << _(" or");
- out << endl;
-
- if (Start == End)
- break;
- ++Start;
- }
- }
- }
-}
- /*}}}*/
-// ShowNew - Show packages to newly install /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowNew(ostream &out,CacheFile &Cache)
-{
- /* Print out a list of packages that are going to be installed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].NewInstall() == true) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CandVersion) + "\n";
- }
- }
-
- ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
-}
- /*}}}*/
-// ShowDel - Show packages to delete /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowDel(ostream &out,CacheFile &Cache)
-{
- /* Print out a list of packages that are going to be removed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].Delete() == true)
- {
- if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
- List += I.FullName(true) + "* ";
- else
- List += I.FullName(true) + " ";
-
- VersionsList += string(Cache[I].CandVersion)+ "\n";
- }
- }
-
- ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
-}
- /*}}}*/
-// ShowKept - Show kept packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowKept(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
- I->CurrentVer == 0 || Cache[I].Delete() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
-}
- /*}}}*/
-// ShowUpgraded - Show upgraded packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowUpgraded(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
-}
- /*}}}*/
-// ShowDowngraded - Show downgraded packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool ShowDowngraded(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
-}
- /*}}}*/
-// ShowHold - Show held but changed packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool ShowHold(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
- I->SelectedState == pkgCache::State::Hold) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- }
-
- return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
-}
- /*}}}*/
-// ShowEssential - Show an essential package warning /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out a warning message that is not to be ignored. It shows
- all essential packages and their dependents that are to be removed.
- It is insanely risky to remove the dependents of an essential package! */
-bool ShowEssential(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- bool *Added = new bool[Cache->Head().PackageCount];
- for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
- Added[I] = false;
-
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
- (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
- continue;
-
- // The essential package is being removed
- if (Cache[I].Delete() == true)
- {
- if (Added[I->ID] == false)
- {
- Added[I->ID] = true;
- List += I.FullName(true) + " ";
- //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
- }
- }
- else
- continue;
-
- if (I->CurrentVer == 0)
- continue;
-
- // Print out any essential package depenendents that are to be removed
- for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; ++D)
- {
- // Skip everything but depends
- if (D->Type != pkgCache::Dep::PreDepends &&
- D->Type != pkgCache::Dep::Depends)
- continue;
-
- pkgCache::PkgIterator P = D.SmartTargetPkg();
- if (Cache[P].Delete() == true)
- {
- if (Added[P->ID] == true)
- continue;
- Added[P->ID] = true;
-
- char S[300];
- snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
- List += S;
- //VersionsList += "\n"; ???
- }
- }
- }
-
- delete [] Added;
- return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
- "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
-}
-
- /*}}}*/
-// Stats - Show some statistics /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void Stats(ostream &out,pkgDepCache &Dep)
-{
- unsigned long Upgrade = 0;
- unsigned long Downgrade = 0;
- unsigned long Install = 0;
- unsigned long ReInstall = 0;
- for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; ++I)
- {
- if (Dep[I].NewInstall() == true)
- Install++;
- else
- {
- if (Dep[I].Upgrade() == true)
- Upgrade++;
- else
- if (Dep[I].Downgrade() == true)
- Downgrade++;
- }
-
- if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
- ReInstall++;
- }
-
- ioprintf(out,_("%lu upgraded, %lu newly installed, "),
- Upgrade,Install);
-
- if (ReInstall != 0)
- ioprintf(out,_("%lu reinstalled, "),ReInstall);
- if (Downgrade != 0)
- ioprintf(out,_("%lu downgraded, "),Downgrade);
-
- ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
- Dep.DelCount(),Dep.KeepCount());
-
- if (Dep.BadCount() != 0)
- ioprintf(out,_("%lu not fully installed or removed.\n"),
- Dep.BadCount());
-}
- /*}}}*/
-// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
-class CacheSetHelperAPTGet : public APT::CacheSetHelper {
- /** \brief stream message should be printed to */
- std::ostream &out;
- /** \brief were things like Task or RegEx used to select packages? */
- bool explicitlyNamed;
-
- APT::PackageSet virtualPkgs;
-
-public:
- std::list<std::pair<pkgCache::VerIterator, std::string> > selectedByRelease;
-
- CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
- explicitlyNamed = true;
- }
-
- virtual void showTaskSelection(pkgCache::PkgIterator const &Pkg, string const &pattern) {
- ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
- Pkg.FullName(true).c_str(), pattern.c_str());
- explicitlyNamed = false;
- }
- virtual void showRegExSelection(pkgCache::PkgIterator const &Pkg, string const &pattern) {
- ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
- Pkg.FullName(true).c_str(), pattern.c_str());
- explicitlyNamed = false;
- }
- virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
- string const &ver, bool const verIsRel) {
- if (ver == Ver.VerStr())
- return;
- selectedByRelease.push_back(make_pair(Ver, ver));
- }
-
- bool showVirtualPackageErrors(pkgCacheFile &Cache) {
- if (virtualPkgs.empty() == true)
- return true;
- for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
- Pkg != virtualPkgs.end(); ++Pkg) {
- if (Pkg->ProvidesList != 0) {
- ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
- Pkg.FullName(true).c_str());
-
- pkgCache::PrvIterator I = Pkg.ProvidesList();
- unsigned short provider = 0;
- for (; I.end() == false; ++I) {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
-
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
- c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
- if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
- c1out << _(" [Installed]");
- c1out << endl;
- ++provider;
- }
- }
- // if we found no candidate which provide this package, show non-candidates
- if (provider == 0)
- for (I = Pkg.ProvidesList(); I.end() == false; ++I)
- c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
- << _(" [Not candidate version]") << endl;
- else
- out << _("You should explicitly select one to install.") << endl;
- } else {
- ioprintf(c1out,
- _("Package %s is not available, but is referred to by another package.\n"
- "This may mean that the package is missing, has been obsoleted, or\n"
- "is only available from another source\n"),Pkg.FullName(true).c_str());
-
- string List;
- string VersionsList;
- SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
- memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
- for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
- Dep.end() == false; ++Dep) {
- if (Dep->Type != pkgCache::Dep::Replaces)
- continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
- continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += Dep.ParentPkg().FullName(true) + " ";
- //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
- }
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
- }
- c1out << std::endl;
- }
- return false;
- }
-
- virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
- if (verset.empty() == false)
- return *(verset.begin());
- else if (ShowError == true) {
- _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
- virtualPkgs.insert(Pkg);
- }
- return pkgCache::VerIterator(Cache, 0);
- }
-
- virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- if (Pkg->ProvidesList != 0)
- {
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
- if (verset.empty() == false)
- return *(verset.begin());
- if (ShowError == true)
- ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
- }
- else
- {
- pkgCache::GrpIterator Grp = Pkg.Group();
- pkgCache::PkgIterator P = Grp.PackageList();
- for (; P.end() != true; P = Grp.NextPkg(P))
- {
- if (P == Pkg)
- continue;
- if (P->CurrentVer != 0) {
- // TRANSLATORS: Note, this is not an interactive question
- ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
- Pkg.FullName(true).c_str(), P.FullName(true).c_str());
- break;
- }
- }
- if (P.end() == true)
- ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
- }
- return pkgCache::VerIterator(Cache, 0);
- }
-
- APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
- APT::VersionSet::Version const &select) {
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
- if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
- return APT::VersionSet();
-
- pkgCache::PkgIterator Prov;
- bool found_one = false;
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false) {
- Prov = PPkg;
- found_one = true;
- } else if (PPkg != Prov) {
- // same group, so it's a foreign package
- if (PPkg->Group == Prov->Group) {
- // do we already have the requested arch?
- if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
- strcmp(Prov.Arch(), "all") == 0 ||
- unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
- continue;
- // see which architecture we prefer more and switch to it
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
- if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
- Prov = PPkg;
- continue;
- }
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true) {
- ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
- Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
- return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
- }
- return APT::VersionSet();
- }
-
- inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
-
-};
- /*}}}*/
-// TryToInstall - Mark a package for installation /*{{{*/
-struct TryToInstall {
- pkgCacheFile* Cache;
- pkgProblemResolver* Fix;
- bool FixBroken;
- unsigned long AutoMarkChanged;
- APT::PackageSet doAutoInstallLater;
-
- TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const FixBroken) : Cache(&Cache), Fix(PM),
- FixBroken(FixBroken), AutoMarkChanged(0) {};
-
- void operator() (pkgCache::VerIterator const &Ver) {
- pkgCache::PkgIterator Pkg = Ver.ParentPkg();
-
- Cache->GetDepCache()->SetCandidateVersion(Ver);
- pkgDepCache::StateCache &State = (*Cache)[Pkg];
-
- // Handle the no-upgrade case
- if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
- ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
- Pkg.FullName(true).c_str());
- // Ignore request for install if package would be new
- else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
- ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
- Pkg.FullName(true).c_str());
- else {
- if (Fix != NULL) {
- Fix->Clear(Pkg);
- Fix->Protect(Pkg);
- }
- Cache->GetDepCache()->MarkInstall(Pkg,false);
-
- if (State.Install() == false) {
- if (_config->FindB("APT::Get::ReInstall",false) == true) {
- if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
- ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
- Pkg.FullName(true).c_str());
- else
- Cache->GetDepCache()->SetReInstall(Pkg, true);
- } else
- ioprintf(c1out,_("%s is already the newest version.\n"),
- Pkg.FullName(true).c_str());
- }
-
- // Install it with autoinstalling enabled (if we not respect the minial
- // required deps or the policy)
- if (FixBroken == false)
- doAutoInstallLater.insert(Pkg);
- }
-
- // see if we need to fix the auto-mark flag
- // e.g. apt-get install foo
- // where foo is marked automatic
- if (State.Install() == false &&
- (State.Flags & pkgCache::Flag::Auto) &&
- _config->FindB("APT::Get::ReInstall",false) == false &&
- _config->FindB("APT::Get::Only-Upgrade",false) == false &&
- _config->FindB("APT::Get::Download-Only",false) == false)
- {
- ioprintf(c1out,_("%s set to manually installed.\n"),
- Pkg.FullName(true).c_str());
- Cache->GetDepCache()->MarkAuto(Pkg,false);
- AutoMarkChanged++;
- }
- }
-
- bool propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > start, std::ostream &out)
- {
- for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
- s != start.end(); ++s)
- Cache->GetDepCache()->SetCandidateVersion(s->first);
-
- bool Success = true;
- std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
- for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
- s != start.end(); ++s)
- {
- Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache)));
- // We continue here even if it failed to enhance the ShowBroken output
- Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed);
- }
- for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
- c != Changed.end(); ++c)
- {
- if (c->second.end() == true)
- ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
- c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str());
- else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group)
- {
- pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache);
- ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(),
- V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str());
- }
- }
- return Success;
- }
-
- void doAutoInstall() {
- for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
- P != doAutoInstallLater.end(); ++P) {
- pkgDepCache::StateCache &State = (*Cache)[P];
- if (State.InstBroken() == false && State.InstPolicyBroken() == false)
- continue;
- Cache->GetDepCache()->MarkInstall(P, true);
- }
- doAutoInstallLater.clear();
- }
-};
- /*}}}*/
-// TryToRemove - Mark a package for removal /*{{{*/
-struct TryToRemove {
- pkgCacheFile* Cache;
- pkgProblemResolver* Fix;
- bool PurgePkgs;
-
- TryToRemove(pkgCacheFile &Cache, pkgProblemResolver *PM) : Cache(&Cache), Fix(PM),
- PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
-
- void operator() (pkgCache::VerIterator const &Ver)
- {
- pkgCache::PkgIterator Pkg = Ver.ParentPkg();
-
- if (Fix != NULL)
- {
- Fix->Clear(Pkg);
- Fix->Protect(Pkg);
- Fix->Remove(Pkg);
- }
-
- if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
- (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
- {
- pkgCache::GrpIterator Grp = Pkg.Group();
- pkgCache::PkgIterator P = Grp.PackageList();
- for (; P.end() != true; P = Grp.NextPkg(P))
- {
- if (P == Pkg)
- continue;
- if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
- {
- // TRANSLATORS: Note, this is not an interactive question
- ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
- Pkg.FullName(true).c_str(), P.FullName(true).c_str());
- break;
- }
- }
- if (P.end() == true)
- ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
-
- // MarkInstall refuses to install packages on hold
- Pkg->SelectedState = pkgCache::State::Hold;
- }
- else
- Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
- }
-};
- /*}}}*/
-// CacheFile::NameComp - QSort compare by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgCache *CacheFile::SortCache = 0;
-int CacheFile::NameComp(const void *a,const void *b)
-{
- if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
- return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
-
- const pkgCache::Package &A = **(pkgCache::Package **)a;
- const pkgCache::Package &B = **(pkgCache::Package **)b;
-
- return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
-}
- /*}}}*/
-// CacheFile::Sort - Sort by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void CacheFile::Sort()
-{
- delete [] List;
- List = new pkgCache::Package *[Cache->Head().PackageCount];
- memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (;I.end() != true; ++I)
- List[I->ID] = I;
-
- SortCache = *this;
- qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
-}
- /*}}}*/
-// CacheFile::CheckDeps - Open the cache file /*{{{*/
-// ---------------------------------------------------------------------
-/* This routine generates the caches and then opens the dependency cache
- and verifies that the system is OK. */
-bool CacheFile::CheckDeps(bool AllowBroken)
-{
- bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
- if (_error->PendingError() == true)
- return false;
- // Check that the system is OK
- if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
- return _error->Error("Internal error, non-zero counts");
-
- // Apply corrections for half-installed packages
- if (pkgApplyStatus(*DCache) == false)
- return false;
-
- if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
- {
- FixBroken = true;
- if ((DCache->PolicyBrokenCount() > 0))
- {
- // upgrade all policy-broken packages with ForceImportantDeps=True
- for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I)
- if ((*DCache)[I].NowPolicyBroken() == true)
- DCache->MarkInstall(I,true,0, false, true);
- }
- }
-
- // Nothing is broken
- if (DCache->BrokenCount() == 0 || AllowBroken == true)
- return true;
-
- // Attempt to fix broken things
- if (FixBroken == true)
- {
- c1out << _("Correcting dependencies...") << flush;
- if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
- {
- c1out << _(" failed.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unable to correct dependencies"));
- }
- if (pkgMinimizeUpgrade(*DCache) == false)
- return _error->Error(_("Unable to minimize the upgrade set"));
-
- c1out << _(" Done") << endl;
- }
- else
- {
- c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unmet dependencies. Try using -f."));
- }
-
- return true;
-}
- /*}}}*/
-// CheckAuth - check if each download comes form a trusted source /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static bool CheckAuth(pkgAcquire& Fetcher)
-{
- string UntrustedList;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
- {
- if (!(*I)->IsTrusted())
- {
- UntrustedList += string((*I)->ShortDesc()) + " ";
- }
- }
-
- if (UntrustedList == "")
- {
- return true;
- }
-
- ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
-
- if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
- {
- c2out << _("Authentication warning overridden.\n");
- return true;
- }
-
- if (_config->FindI("quiet",0) < 2
- && _config->FindB("APT::Get::Assume-Yes",false) == false)
- {
- c2out << _("Install these packages without verification?") << flush;
- if (!YnPrompt(false))
- return _error->Error(_("Some packages could not be authenticated"));
-
- return true;
- }
- else if (_config->FindB("APT::Get::Force-Yes",false) == true)
- {
- return true;
- }
-
- return _error->Error(_("There are problems and -y was used without --force-yes"));
-}
- /*}}}*/
-// InstallPackages - Actually download and install the packages /*{{{*/
-// ---------------------------------------------------------------------
-/* This displays the informative messages describing what is going to
- happen and then calls the download routines */
-bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
- bool Safety = true)
-{
- if (_config->FindB("APT::Get::Purge",false) == true)
- {
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (; I.end() == false; ++I)
- {
- if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
- Cache->MarkDelete(I,true);
- }
- }
-
- bool Fail = false;
- bool Essential = false;
-
- // Show all the various warning indicators
- ShowDel(c1out,Cache);
- ShowNew(c1out,Cache);
- if (ShwKept == true)
- ShowKept(c1out,Cache);
- Fail |= !ShowHold(c1out,Cache);
- if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
- ShowUpgraded(c1out,Cache);
- Fail |= !ShowDowngraded(c1out,Cache);
- if (_config->FindB("APT::Get::Download-Only",false) == false)
- Essential = !ShowEssential(c1out,Cache);
- Fail |= Essential;
- Stats(c1out,Cache);
-
- // Sanity check
- if (Cache->BrokenCount() != 0)
- {
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
- }
-
- if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
- Cache->BadCount() == 0)
- return true;
-
- // No remove flag
- if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
- return _error->Error(_("Packages need to be removed but remove is disabled."));
-
- // Run the simulator ..
- if (_config->FindB("APT::Get::Simulate") == true)
- {
- pkgSimulate PM(Cache);
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed)
- return false;
- if (Res != pkgPackageManager::Completed)
- return _error->Error(_("Internal error, Ordering didn't finish"));
- return true;
- }
-
- // Create the text record parser
- pkgRecords Recs(Cache);
- if (_error->PendingError() == true)
- return false;
-
- // Create the download object
- pkgAcquire Fetcher;
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
- if (_config->FindB("APT::Get::Print-URIs", false) == true)
- {
- // force a hashsum for compatibility reasons
- _config->CndSet("Acquire::ForceHash", "md5sum");
- }
- else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
- return false;
-
- // Read the source list
- if (Cache.BuildSourceList() == false)
- return false;
- pkgSourceList *List = Cache.GetSourceList();
-
- // Create the package manager and prepare to download
- SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
- if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
- _error->PendingError() == true)
- return false;
-
- // Display statistics
- unsigned long long FetchBytes = Fetcher.FetchNeeded();
- unsigned long long FetchPBytes = Fetcher.PartialPresent();
- unsigned long long DebBytes = Fetcher.TotalNeeded();
- if (DebBytes != Cache->DebSize())
- {
- c0out << DebBytes << ',' << Cache->DebSize() << endl;
- c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl;
- }
-
- // Number of bytes
- if (DebBytes != FetchBytes)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
- SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
- else if (DebBytes != 0)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("Need to get %sB of archives.\n"),
- SizeToStr(DebBytes).c_str());
-
- // Size delta
- if (Cache->UsrSize() >= 0)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
- SizeToStr(Cache->UsrSize()).c_str());
- else
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
- SizeToStr(-1*Cache->UsrSize()).c_str());
-
- if (_error->PendingError() == true)
- return false;
-
- /* Check for enough free space, but only if we are actually going to
- download */
- if (_config->FindB("APT::Get::Print-URIs") == false &&
- _config->FindB("APT::Get::Download",true) == true)
- {
- struct statvfs Buf;
- string OutputDir = _config->FindDir("Dir::Cache::Archives");
- if (statvfs(OutputDir.c_str(),&Buf) != 0) {
- if (errno == EOVERFLOW)
- return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
- OutputDir.c_str());
- else
- return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
- OutputDir.c_str());
- } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
- {
- struct statfs Stat;
- if (statfs(OutputDir.c_str(),&Stat) != 0
-#if HAVE_STRUCT_STATFS_F_TYPE
- || unsigned(Stat.f_type) != RAMFS_MAGIC
-#endif
- )
- return _error->Error(_("You don't have enough free space in %s."),
- OutputDir.c_str());
- }
- }
-
- // Fail safe check
- if (_config->FindI("quiet",0) >= 2 ||
- _config->FindB("APT::Get::Assume-Yes",false) == true)
- {
- if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
- return _error->Error(_("There are problems and -y was used without --force-yes"));
- }
-
- if (Essential == true && Safety == true)
- {
- if (_config->FindB("APT::Get::Trivial-Only",false) == true)
- return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
-
- // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
- // careful with hard to type or special characters (like non-breaking spaces)
- const char *Prompt = _("Yes, do as I say!");
- ioprintf(c2out,
- _("You are about to do something potentially harmful.\n"
- "To continue type in the phrase '%s'\n"
- " ?] "),Prompt);
- c2out << flush;
- if (AnalPrompt(Prompt) == false)
- {
- c2out << _("Abort.") << endl;
- exit(1);
- }
- }
- else
- {
- // Prompt to continue
- if (Ask == true || Fail == true)
- {
- if (_config->FindB("APT::Get::Trivial-Only",false) == true)
- return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
-
- if (_config->FindI("quiet",0) < 2 &&
- _config->FindB("APT::Get::Assume-Yes",false) == false)
- {
- c2out << _("Do you want to continue?") << flush;
-
- if (YnPrompt() == false)
- {
- c2out << _("Abort.") << endl;
- exit(1);
- }
- }
- }
- }
-
- // Just print out the uris an exit if the --print-uris flag was used
- if (_config->FindB("APT::Get::Print-URIs") == true)
- {
- pkgAcquire::UriIterator I = Fetcher.UriBegin();
- for (; I != Fetcher.UriEnd(); ++I)
- cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
- I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
- return true;
- }
-
- if (!CheckAuth(Fetcher))
- return false;
-
- /* Unlock the dpkg lock if we are not going to be doing an install
- after. */
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- _system->UnLock();
-
- // Run it
- while (1)
- {
- bool Transient = false;
- if (_config->FindB("APT::Get::Download",true) == false)
- {
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
- {
- if ((*I)->Local == true)
- {
- ++I;
- continue;
- }
-
- // Close the item and check if it was found in cache
- (*I)->Finished();
- if ((*I)->Complete == false)
- Transient = true;
-
- // Clear it out of the fetch list
- delete *I;
- I = Fetcher.ItemsBegin();
- }
- }
-
- if (Fetcher.Run() == pkgAcquire::Failed)
- return false;
-
- // Print out errors
- bool Failed = false;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone &&
- (*I)->Complete == true)
- continue;
-
- if ((*I)->Status == pkgAcquire::Item::StatIdle)
- {
- Transient = true;
- // Failed = true;
- continue;
- }
-
- fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
- (*I)->ErrorText.c_str());
- Failed = true;
- }
-
- /* If we are in no download mode and missing files and there were
- 'failures' then the user must specify -m. Furthermore, there
- is no such thing as a transient error in no-download mode! */
- if (Transient == true &&
- _config->FindB("APT::Get::Download",true) == false)
- {
- Transient = false;
- Failed = true;
- }
-
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- {
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- return _error->Error(_("Some files failed to download"));
- c1out << _("Download complete and in download only mode") << endl;
- return true;
- }
-
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- {
- return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
- }
-
- if (Transient == true && Failed == true)
- return _error->Error(_("--fix-missing and media swapping is not currently supported"));
-
- // Try to deal with missing package files
- if (Failed == true && PM->FixMissing() == false)
- {
- cerr << _("Unable to correct missing packages.") << endl;
- return _error->Error(_("Aborting install."));
- }
-
- _system->UnLock();
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
- return false;
- if (Res == pkgPackageManager::Completed)
- break;
-
- // Reload the fetcher object and loop again for media swapping
- Fetcher.Shutdown();
- if (PM->GetArchives(&Fetcher,List,&Recs) == false)
- return false;
-
- _system->Lock();
- }
-
- std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
- if (disappearedPkgs.empty() == true)
- return true;
-
- string disappear;
- for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
- d != disappearedPkgs.end(); ++d)
- disappear.append(*d).append(" ");
-
- ShowList(c1out, P_("The following package disappeared from your system as\n"
- "all files have been overwritten by other packages:",
- "The following packages disappeared from your system as\n"
- "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, "");
- c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl;
-
- return true;
-}
- /*}}}*/
// TryToInstallBuildDep - Try to install a single package /*{{{*/
// ---------------------------------------------------------------------
/* This used to be inlined in DoInstall, but with the advent of regex package
@@ -1667,497 +302,6 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
return Last;
}
/*}}}*/
-// DoUpdate - Update the package lists /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool DoUpdate(CommandLine &CmdL)
-{
- if (CmdL.FileSize() != 1)
- return _error->Error(_("The update command takes no arguments"));
-
- CacheFile Cache;
-
- // Get the source list
- if (Cache.BuildSourceList() == false)
- return false;
- pkgSourceList *List = Cache.GetSourceList();
-
- // Create the progress
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
-
- // Just print out the uris an exit if the --print-uris flag was used
- if (_config->FindB("APT::Get::Print-URIs") == true)
- {
- // force a hashsum for compatibility reasons
- _config->CndSet("Acquire::ForceHash", "md5sum");
-
- // get a fetcher
- pkgAcquire Fetcher;
- if (Fetcher.Setup(&Stat) == false)
- return false;
-
- // Populate it with the source selection and get all Indexes
- // (GetAll=true)
- if (List->GetIndexes(&Fetcher,true) == false)
- return false;
-
- pkgAcquire::UriIterator I = Fetcher.UriBegin();
- for (; I != Fetcher.UriEnd(); ++I)
- cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
- I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
- return true;
- }
-
- // do the work
- if (_config->FindB("APT::Get::Download",true) == true)
- ListUpdate(Stat, *List);
-
- // Rebuild the cache.
- if (_config->FindB("pkgCacheFile::Generate", true) == true)
- {
- pkgCacheFile::RemoveCaches();
- if (Cache.BuildCaches() == false)
- return false;
- }
-
- return true;
-}
- /*}}}*/
-// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
-// ---------------------------------------------------------------------
-/* Remove unused automatic packages */
-bool DoAutomaticRemove(CacheFile &Cache)
-{
- bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
- bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
- bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
-
- pkgDepCache::ActionGroup group(*Cache);
- if(Debug)
- std::cout << "DoAutomaticRemove()" << std::endl;
-
- if (doAutoRemove == true &&
- _config->FindB("APT::Get::Remove",true) == false)
- {
- c1out << _("We are not supposed to delete stuff, can't start "
- "AutoRemover") << std::endl;
- return false;
- }
-
- bool purgePkgs = _config->FindB("APT::Get::Purge", false);
- bool smallList = (hideAutoRemove == false &&
- strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
-
- unsigned long autoRemoveCount = 0;
- APT::PackageSet tooMuch;
- APT::PackageList autoRemoveList;
- // look over the cache to see what can be removed
- for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
- {
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
- if (Cache[Pkg].Garbage)
- {
- if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
- if(Debug)
- std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
-
- if (doAutoRemove)
- {
- if(Pkg.CurrentVer() != 0 &&
- Pkg->CurrentState != pkgCache::State::ConfigFiles)
- Cache->MarkDelete(Pkg, purgePkgs, 0, false);
- else
- Cache->MarkKeep(Pkg, false, false);
- }
- else
- {
- if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
- autoRemoveList.insert(Pkg);
- // if the package is a new install and already garbage we don't need to
- // install it in the first place, so nuke it instead of show it
- if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
- {
- if (Pkg.CandVersion() != 0)
- tooMuch.insert(Pkg);
- Cache->MarkDelete(Pkg, false, 0, false);
- }
- // only show stuff in the list that is not yet marked for removal
- else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
- ++autoRemoveCount;
- }
- }
- }
-
- // we could have removed a new dependency of a garbage package,
- // so check if a reverse depends is broken and if so install it again.
- if (tooMuch.empty() == false && (Cache->BrokenCount() != 0 || Cache->PolicyBrokenCount() != 0))
- {
- bool Changed;
- do {
- Changed = false;
- for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
- Pkg != tooMuch.end() && Changed == false; ++Pkg)
- {
- APT::PackageSet too;
- too.insert(*Pkg);
- for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
- Prv.end() == false; ++Prv)
- too.insert(Prv.ParentPkg());
- for (APT::PackageSet::const_iterator P = too.begin();
- P != too.end() && Changed == false; ++P) {
- for (pkgCache::DepIterator R = P.RevDependsList();
- R.end() == false; ++R)
- {
- if (R.IsNegative() == true ||
- Cache->IsImportantDep(R) == false)
- continue;
- pkgCache::PkgIterator N = R.ParentPkg();
- if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
- continue;
- if (Debug == true)
- std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
- Cache->MarkInstall(Pkg, false, 0, false);
- if (hideAutoRemove == false)
- ++autoRemoveCount;
- tooMuch.erase(Pkg);
- Changed = true;
- break;
- }
- }
- }
- } while (Changed == true);
- }
-
- std::string autoremovelist, autoremoveversions;
- if (smallList == false && autoRemoveCount != 0)
- {
- for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
- {
- if (Cache[Pkg].Garbage == false)
- continue;
- autoremovelist += Pkg.FullName(true) + " ";
- autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
- }
- }
-
- // Now see if we had destroyed anything (if we had done anything)
- if (Cache->BrokenCount() != 0)
- {
- c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
- "shouldn't happen. Please file a bug report against apt.") << endl;
- c1out << endl;
- c1out << _("The following information may help to resolve the situation:") << endl;
- c1out << endl;
- ShowBroken(c1out,Cache,false);
-
- return _error->Error(_("Internal Error, AutoRemover broke stuff"));
- }
-
- // if we don't remove them, we should show them!
- if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
- {
- if (smallList == false)
- ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
- "The following packages were automatically installed and are no longer required:",
- autoRemoveCount), autoremovelist, autoremoveversions);
- else
- ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
- "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
- c1out << P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount) << std::endl;
- }
- return true;
-}
- /*}}}*/
-// DoUpgrade - Upgrade all packages /*{{{*/
-// ---------------------------------------------------------------------
-/* Upgrade all packages without installing new packages or erasing old
- packages */
-bool DoUpgrade(CommandLine &CmdL)
-{
- CacheFile Cache;
- if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
- return false;
-
- // Do the upgrade
- if (pkgAllUpgrade(Cache) == false)
- {
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, AllUpgrade broke stuff"));
- }
-
- return InstallPackages(Cache,true);
-}
- /*}}}*/
-// DoInstall - Install packages from the command line /*{{{*/
-// ---------------------------------------------------------------------
-/* Install named packages */
-bool DoInstall(CommandLine &CmdL)
-{
- CacheFile Cache;
- if (Cache.OpenForInstall() == false ||
- Cache.CheckDeps(CmdL.FileSize() != 1) == false)
- return false;
-
- // Enter the special broken fixing mode if the user specified arguments
- bool BrokenFix = false;
- if (Cache->BrokenCount() != 0)
- BrokenFix = true;
-
- pkgProblemResolver* Fix = NULL;
- if (_config->FindB("APT::Get::CallResolver", true) == true)
- Fix = new pkgProblemResolver(Cache);
-
- static const unsigned short MOD_REMOVE = 1;
- static const unsigned short MOD_INSTALL = 2;
-
- unsigned short fallback = MOD_INSTALL;
- if (strcasecmp(CmdL.FileList[0],"remove") == 0)
- fallback = MOD_REMOVE;
- else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
- {
- _config->Set("APT::Get::Purge", true);
- fallback = MOD_REMOVE;
- }
- else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
- {
- _config->Set("APT::Get::AutomaticRemove", "true");
- fallback = MOD_REMOVE;
- }
-
- std::list<APT::VersionSet::Modifier> mods;
- mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
- mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
- CacheSetHelperAPTGet helper(c0out);
- std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
- CmdL.FileList + 1, mods, fallback, helper);
-
- if (_error->PendingError() == true)
- {
- helper.showVirtualPackageErrors(Cache);
- if (Fix != NULL)
- delete Fix;
- return false;
- }
-
-
- TryToInstall InstallAction(Cache, Fix, BrokenFix);
- TryToRemove RemoveAction(Cache, Fix);
-
- // new scope for the ActionGroup
- {
- pkgDepCache::ActionGroup group(Cache);
- unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
-
- for (unsigned short i = 0; order[i] != 0; ++i)
- {
- if (order[i] == MOD_INSTALL)
- InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
- else if (order[i] == MOD_REMOVE)
- RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
- }
-
- if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
- {
- for (unsigned short i = 0; order[i] != 0; ++i)
- {
- if (order[i] != MOD_INSTALL)
- continue;
- InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
- InstallAction.doAutoInstall();
- }
- }
-
- if (_error->PendingError() == true)
- {
- if (Fix != NULL)
- delete Fix;
- return false;
- }
-
- /* If we are in the Broken fixing mode we do not attempt to fix the
- problems. This is if the user invoked install without -f and gave
- packages */
- if (BrokenFix == true && Cache->BrokenCount() != 0)
- {
- c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
- ShowBroken(c1out,Cache,false);
- if (Fix != NULL)
- delete Fix;
- return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
- }
-
- if (Fix != NULL)
- {
- // Call the scored problem resolver
- Fix->Resolve(true);
- delete Fix;
- }
-
- // Now we check the state of the packages,
- if (Cache->BrokenCount() != 0)
- {
- c1out <<
- _("Some packages could not be installed. This may mean that you have\n"
- "requested an impossible situation or if you are using the unstable\n"
- "distribution that some required packages have not yet been created\n"
- "or been moved out of Incoming.") << endl;
- /*
- if (Packages == 1)
- {
- c1out << endl;
- c1out <<
- _("Since you only requested a single operation it is extremely likely that\n"
- "the package is simply not installable and a bug report against\n"
- "that package should be filed.") << endl;
- }
- */
-
- c1out << _("The following information may help to resolve the situation:") << endl;
- c1out << endl;
- ShowBroken(c1out,Cache,false);
- if (_error->PendingError() == true)
- return false;
- else
- return _error->Error(_("Broken packages"));
- }
- }
- if (!DoAutomaticRemove(Cache))
- return false;
-
- /* Print out a list of packages that are going to be installed extra
- to what the user asked */
- if (Cache->InstCount() != verset[MOD_INSTALL].size())
- {
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if ((*Cache)[I].Install() == false)
- continue;
- pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
-
- if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CandVersion) + "\n";
- }
-
- ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
- }
-
- /* Print out a list of suggested and recommended packages */
- {
- string SuggestsList, RecommendsList;
- string SuggestsVersions, RecommendsVersions;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
-
- /* Just look at the ones we want to install */
- if ((*Cache)[Pkg].Install() == false)
- continue;
-
- // get the recommends/suggests for the candidate ver
- pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
- for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
- {
- pkgCache::DepIterator Start;
- pkgCache::DepIterator End;
- D.GlobOr(Start,End); // advances D
-
- // FIXME: we really should display a or-group as a or-group to the user
- // the problem is that ShowList is incapable of doing this
- string RecommendsOrList,RecommendsOrVersions;
- string SuggestsOrList,SuggestsOrVersions;
- bool foundInstalledInOrGroup = false;
- for(;;)
- {
- /* Skip if package is installed already, or is about to be */
- string target = Start.TargetPkg().FullName(true) + " ";
- pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
- if (TarPkg->SelectedState == pkgCache::State::Install ||
- TarPkg->SelectedState == pkgCache::State::Hold ||
- Cache[Start.TargetPkg()].Install())
- {
- foundInstalledInOrGroup=true;
- break;
- }
-
- /* Skip if we already saw it */
- if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
- {
- foundInstalledInOrGroup=true;
- break;
- }
-
- // this is a dep on a virtual pkg, check if any package that provides it
- // should be installed
- if(Start.TargetPkg().ProvidesList() != 0)
- {
- pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
- for (; I.end() == false; ++I)
- {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() &&
- Pkg.CurrentVer() != 0)
- foundInstalledInOrGroup=true;
- }
- }
-
- if (Start->Type == pkgCache::Dep::Suggests)
- {
- SuggestsOrList += target;
- SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
- }
-
- if (Start->Type == pkgCache::Dep::Recommends)
- {
- RecommendsOrList += target;
- RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
- }
-
- if (Start >= End)
- break;
- ++Start;
- }
-
- if(foundInstalledInOrGroup == false)
- {
- RecommendsList += RecommendsOrList;
- RecommendsVersions += RecommendsOrVersions;
- SuggestsList += SuggestsOrList;
- SuggestsVersions += SuggestsOrVersions;
- }
-
- }
- }
-
- ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
- ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
-
- }
-
- // if nothing changed in the cache, but only the automark information
- // we write the StateFile here, otherwise it will be written in
- // cache.commit()
- if (InstallAction.AutoMarkChanged > 0 &&
- Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
- Cache->BadCount() == 0 &&
- _config->FindB("APT::Get::Simulate",false) == false)
- Cache->writeStateFile(NULL);
-
- // See if we need to prompt
- // FIXME: check if really the packages in the set are going to be installed
- if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
- return InstallPackages(Cache,false,false);
-
- return InstallPackages(Cache,false);
-}
- /*}}}*/
/* mark packages as automatically/manually installed. {{{*/
bool DoMarkAuto(CommandLine &CmdL)
{
@@ -2206,6 +350,9 @@ bool DoMarkAuto(CommandLine &CmdL)
/* Intelligent upgrader that will install and remove packages at will */
bool DoDistUpgrade(CommandLine &CmdL)
{
+ if (CmdL.FileSize() != 1)
+ return _error->Error(_("The dist-upgrade command takes no arguments"));
+
CacheFile Cache;
if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
return false;
@@ -2585,7 +732,7 @@ bool DoSource(CommandLine &CmdL)
if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
continue;
queued.insert(Last->Index().ArchiveURI(I->Path));
-
+
// check if we have a file with that md5 sum already localy
if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))
{
@@ -3367,23 +1514,6 @@ bool DoChangelog(CommandLine &CmdL)
return true;
}
/*}}}*/
-// DoMoo - Never Ask, Never Tell /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool DoMoo(CommandLine &CmdL)
-{
- cout <<
- " (__) \n"
- " (oo) \n"
- " /------\\/ \n"
- " / | || \n"
- " * /\\---/\\ \n"
- " ~~ ~~ \n"
- "....\"Have you mooed today?\"...\n";
-
- return true;
-}
- /*}}}*/
// ShowHelp - Show a help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -3494,58 +1624,17 @@ void SigWinch(int)
#endif
}
/*}}}*/
+
+bool DoUpgrade(CommandLine &CmdL)
+{
+ if (_config->FindB("APT::Get::UpgradeAllowNew", false) == true)
+ return DoUpgradeWithAllowNewPackages(CmdL);
+ else
+ return DoUpgradeNoNewPackages(CmdL);
+}
+
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'V',"verbose-versions","APT::Get::Show-Versions",0},
- {'q',"quiet","quiet",CommandLine::IntLevel},
- {'q',"silent","quiet",CommandLine::IntLevel},
- {'d',"download-only","APT::Get::Download-Only",0},
- {'b',"compile","APT::Get::Compile",0},
- {'b',"build","APT::Get::Compile",0},
- {'s',"simulate","APT::Get::Simulate",0},
- {'s',"just-print","APT::Get::Simulate",0},
- {'s',"recon","APT::Get::Simulate",0},
- {'s',"dry-run","APT::Get::Simulate",0},
- {'s',"no-act","APT::Get::Simulate",0},
- {'y',"yes","APT::Get::Assume-Yes",0},
- {'y',"assume-yes","APT::Get::Assume-Yes",0},
- {0,"assume-no","APT::Get::Assume-No",0},
- {'f',"fix-broken","APT::Get::Fix-Broken",0},
- {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
- {'m',"ignore-missing","APT::Get::Fix-Missing",0},
- {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
- {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
- {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg},
- {0,"download","APT::Get::Download",0},
- {0,"fix-missing","APT::Get::Fix-Missing",0},
- {0,"ignore-hold","APT::Ignore-Hold",0},
- {0,"upgrade","APT::Get::upgrade",0},
- {0,"only-upgrade","APT::Get::Only-Upgrade",0},
- {0,"force-yes","APT::Get::force-yes",0},
- {0,"print-uris","APT::Get::Print-URIs",0},
- {0,"diff-only","APT::Get::Diff-Only",0},
- {0,"debian-only","APT::Get::Diff-Only",0},
- {0,"tar-only","APT::Get::Tar-Only",0},
- {0,"dsc-only","APT::Get::Dsc-Only",0},
- {0,"purge","APT::Get::Purge",0},
- {0,"list-cleanup","APT::Get::List-Cleanup",0},
- {0,"reinstall","APT::Get::ReInstall",0},
- {0,"trivial-only","APT::Get::Trivial-Only",0},
- {0,"remove","APT::Get::Remove",0},
- {0,"only-source","APT::Get::Only-Source",0},
- {0,"arch-only","APT::Get::Arch-Only",0},
- {0,"auto-remove","APT::Get::AutomaticRemove",0},
- {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
- {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
- {0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean},
- {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
- {0,"solver","APT::Solver",CommandLine::HasArg},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
{"upgrade",&DoUpgrade},
{"install",&DoInstall},
@@ -3567,12 +1656,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-get", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -3593,33 +1684,15 @@ int main(int argc,const char *argv[]) /*{{{*/
return 0;
}
- // simulate user-friendly if apt-get has no root privileges
- if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true &&
- (CmdL.FileSize() == 0 ||
- (strcmp(CmdL.FileList[0], "source") != 0 && strcmp(CmdL.FileList[0], "download") != 0 &&
- strcmp(CmdL.FileList[0], "changelog") != 0)))
- {
- if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
- cout << _("NOTE: This is only a simulation!\n"
- " apt-get needs root privileges for real execution.\n"
- " Keep also in mind that locking is deactivated,\n"
- " so don't depend on the relevance to the real current situation!"
- ) << std::endl;
- _config->Set("Debug::NoLocking",true);
- }
+ // see if we are in simulate mode
+ CheckSimulateMode(CmdL);
// Deal with stdout not being a tty
if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Setup the output streams
- c0out.rdbuf(cout.rdbuf());
- c1out.rdbuf(cout.rdbuf());
- c2out.rdbuf(cout.rdbuf());
- if (_config->FindI("quiet",0) > 0)
- c0out.rdbuf(devnull.rdbuf());
- if (_config->FindI("quiet",0) > 1)
- c1out.rdbuf(devnull.rdbuf());
+ InitOutput();
// Setup the signals
signal(SIGPIPE,SIG_IGN);
diff --git a/cmdline/apt-key b/cmdline/apt-key
index 2c087acbc..713a41c07 100755
--- a/cmdline/apt-key
+++ b/cmdline/apt-key
@@ -3,27 +3,39 @@
set -e
unset GREP_OPTIONS
-# We don't use a secret keyring, of course, but gpg panics and
-# implodes if there isn't one available
-SECRETKEYRING="$(mktemp)"
-trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
-GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring ${SECRETKEYRING}"
+GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring"
-if [ "$(id -u)" -eq 0 ]; then
- # we could use a tmpfile here too, but creation of this tends to be time-consuming
- eval $(apt-config shell TRUSTDBDIR Dir::Etc/d)
- GPG_CMD="$GPG_CMD --trustdb-name ${TRUSTDBDIR}/trustdb.gpg"
-fi
+# gpg needs a trustdb to function, but it can't be invalid (not even empty)
+# so we create a temporary directory to store our fresh readable trustdb in
+TRUSTDBDIR="$(mktemp -d)"
+CURRENTTRAP="${CURRENTTRAP} rm -rf '${TRUSTDBDIR}';"
+trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+chmod 700 "$TRUSTDBDIR"
+# We also don't use a secret keyring, of course, but gpg panics and
+# implodes if there isn't one available - and writeable for imports
+SECRETKEYRING="${TRUSTDBDIR}/secring.gpg"
+touch $SECRETKEYRING
+GPG_CMD="$GPG_CMD --secret-keyring $SECRETKEYRING"
+GPG_CMD="$GPG_CMD --trustdb-name ${TRUSTDBDIR}/trustdb.gpg"
+
+# now create the trustdb with an (empty) dummy keyring
+$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING
+# and make sure that gpg isn't trying to update the file
+GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
GPG="$GPG_CMD"
MASTER_KEYRING=""
-ARCHIVE_KEYRING_URI=""
#MASTER_KEYRING=/usr/share/keyrings/debian-master-keyring.gpg
+eval $(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring)
+ARCHIVE_KEYRING_URI=""
#ARCHIVE_KEYRING_URI=http://ftp.debian.org/debian/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)
ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring)
REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
+eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)
requires_root() {
if [ "$(id -u)" -ne 0 ]; then
@@ -139,6 +151,60 @@ update() {
fi
}
+remove_key_from_keyring() {
+ local GPG="$GPG_CMD --keyring $1"
+ # check if the key is in this keyring: the key id is in the 5 column at the end
+ if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then
+ return
+ fi
+ if [ ! -w "$1" ]; then
+ echo >&2 "Key ${2} is in keyring ${1}, but can't be removed as it is read only."
+ return
+ fi
+ # check if it is the only key in the keyring and if so remove the keyring alltogether
+ if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then
+ mv -f "$1" "${1}~" # behave like gpg
+ return
+ fi
+ # we can't just modify pointed to files as these might be in /usr or something
+ local REALTARGET
+ if [ -L "$1" ]; then
+ REALTARGET="$(readlink -f "$1")"
+ mv -f "$1" "${1}.dpkg-tmp"
+ cp -a "$REALTARGET" "$1"
+ ls "$(dirname $1)"
+ fi
+ # delete the key from the keyring
+ $GPG --batch --delete-key --yes "$2"
+ if [ -n "$REALTARGET" ]; then
+ # the real backup is the old link, not the copy we made
+ mv -f "${1}.dpkg-tmp" "${1}~"
+ fi
+}
+
+remove_key() {
+ requires_root
+
+ # if a --keyring was given, just remove from there
+ if [ -n "$FORCED_KEYRING" ]; then
+ remove_key_from_keyring "$FORCED_KEYRING" "$1"
+ else
+ # otherwise all known keyrings are up for inspection
+ local TRUSTEDFILE="/etc/apt/trusted.gpg"
+ eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
+ eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
+ remove_key_from_keyring "$TRUSTEDFILE" "$1"
+ TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
+ eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
+ if [ -d "$TRUSTEDPARTS" ]; then
+ for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
+ remove_key_from_keyring "$trusted" "$1"
+ done
+ fi
+ fi
+ echo "OK"
+}
+
usage() {
echo "Usage: apt-key [--keyring file] [command] [arguments]"
@@ -158,39 +224,54 @@ usage() {
echo "If no specific keyring file is given the command applies to all keyring files."
}
-# Determine on which keyring we want to work
-if [ "$1" = "--keyring" ]; then
- #echo "keyfile given"
- shift
- TRUSTEDFILE="$1"
- if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
- GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
- else
- echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
- exit 1
- fi
- shift
-# otherwise use the default
-else
- #echo "generate list"
- TRUSTEDFILE="/etc/apt/trusted.gpg"
- eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
- eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
- if [ -r "$TRUSTEDFILE" ]; then
- GPG="$GPG --keyring $TRUSTEDFILE"
- fi
- GPG="$GPG --primary-keyring $TRUSTEDFILE"
- TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
- eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
- if [ -d "$TRUSTEDPARTS" ]; then
- #echo "parts active"
- for trusted in $(run-parts --list $TRUSTEDPARTS --regex '^.*\.gpg$'); do
- #echo "part -> $trusted"
- GPG="$GPG --keyring $trusted"
- done
- fi
+while [ -n "$1" ]; do
+ case "$1" in
+ --keyring)
+ shift
+ TRUSTEDFILE="$1"
+ FORCED_KEYRING="$1"
+ if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
+ GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
+ else
+ echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
+ exit 1
+ fi
+ shift
+ ;;
+ --fakeroot)
+ requires_root() { true; }
+ shift
+ ;;
+ --*)
+ echo >&2 "Unknown option: $1"
+ usage
+ exit 1;;
+ *)
+ break;;
+ esac
+done
+
+if [ -z "$TRUSTEDFILE" ]; then
+ TRUSTEDFILE="/etc/apt/trusted.gpg"
+ eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
+ eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
+ if [ -r "$TRUSTEDFILE" ]; then
+ GPG="$GPG --keyring $TRUSTEDFILE"
+ fi
+ GPG="$GPG --primary-keyring $TRUSTEDFILE"
+ TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
+ eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
+ if [ -d "$TRUSTEDPARTS" ]; then
+ # strip / suffix as gpg will double-slash in that case (#665411)
+ STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
+ if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
+ TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
+ fi
+ for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
+ GPG="$GPG --keyring $trusted"
+ done
+ fi
fi
-#echo "COMMAND: $GPG"
command="$1"
if [ -z "$command" ]; then
@@ -213,10 +294,8 @@ case "$command" in
echo "OK"
;;
del|rm|remove)
- requires_root
init_keyring "$TRUSTEDFILE"
- $GPG --quiet --batch --delete-key --yes "$1"
- echo "OK"
+ remove_key "$1"
;;
update)
init_keyring "$TRUSTEDFILE"
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
index 4c0fc2893..eb3410be1 100644
--- a/cmdline/apt-mark.cc
+++ b/cmdline/apt-mark.cc
@@ -24,6 +24,8 @@
#include <sys/wait.h>
#include <fcntl.h>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
using namespace std;
@@ -400,21 +402,6 @@ bool ShowHelp(CommandLine &CmdL)
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {0,"version","version",0},
- {'q',"quiet","quiet",CommandLine::IntLevel},
- {'q',"silent","quiet",CommandLine::IntLevel},
- {'v',"verbose","APT::MarkAuto::Verbose",0},
- {'s',"simulate","APT::Mark::Simulate",0},
- {'s',"just-print","APT::Mark::Simulate",0},
- {'s',"recon","APT::Mark::Simulate",0},
- {'s',"dry-run","APT::Mark::Simulate",0},
- {'s',"no-act","APT::Mark::Simulate",0},
- {'f',"file","Dir::State::extended_states",CommandLine::HasArg},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
{"auto",&DoAuto},
{"manual",&DoAuto},
@@ -432,12 +419,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"unmarkauto", &DoMarkAuto},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-mark", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
diff --git a/cmdline/apt.cc b/cmdline/apt.cc
new file mode 100644
index 000000000..e30967ec2
--- /dev/null
+++ b/cmdline/apt.cc
@@ -0,0 +1,158 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ apt - CLI UI for apt
+
+ Returns 100 on failure, 0 on success.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include<config.h>
+
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <iomanip>
+#include <algorithm>
+
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <apti18n.h>
+
+#include <apt-private/private-list.h>
+#include <apt-private/private-search.h>
+#include <apt-private/private-install.h>
+#include <apt-private/private-output.h>
+#include <apt-private/private-update.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-moo.h>
+#include <apt-private/private-upgrade.h>
+#include <apt-private/private-show.h>
+#include <apt-private/private-main.h>
+ /*}}}*/
+
+bool ShowHelp(CommandLine &CmdL)
+{
+ ioprintf(c1out,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
+ COMMON_ARCH,__DATE__,__TIME__);
+
+ // FIXME: generate from CommandLine
+ c1out <<
+ _("Usage: apt [options] command\n"
+ "\n"
+ "CLI for apt.\n"
+ "Commands: \n"
+ " list - list packages based on package names\n"
+ " search - search in package descriptions\n"
+ " show - show package details\n"
+ "\n"
+ " update - update list of available packages\n"
+ " install - install packages\n"
+ " upgrade - upgrade the systems packages\n"
+ );
+
+ return true;
+}
+
+int main(int argc, const char *argv[]) /*{{{*/
+{
+ CommandLine::Dispatch Cmds[] = {{"list",&List},
+ {"search", &FullTextSearch},
+ {"show", &APT::Cmd::ShowPackage},
+ // needs root
+ {"install",&DoInstall},
+ {"remove", &DoInstall},
+ {"update",&DoUpdate},
+ {"upgrade",&DoUpgradeWithAllowNewPackages},
+ // helper
+ {"moo",&DoMoo},
+ {"help",&ShowHelp},
+ {0,0}};
+
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt", CommandLine::GetCommand(Cmds, argc, argv));
+
+ if(!isatty(1))
+ {
+ std::cerr << std::endl
+ << "WARNING WARNING "
+ << argv[0]
+ << " is *NOT* intended for scripts "
+ << "use at your own peril^Wrisk"
+ << std::endl
+ << std::endl;
+ }
+
+ InitOutput();
+
+ // Set up gettext support
+ setlocale(LC_ALL,"");
+ textdomain(PACKAGE);
+
+ if(pkgInitConfig(*_config) == false)
+ {
+ _error->DumpErrors();
+ return 100;
+ }
+
+ // FIXME: move into a new libprivate/private-install.cc:Install()
+ _config->Set("DPkgPM::Progress", "1");
+ _config->Set("Apt::Color", "1");
+
+ // Parse the command line and initialize the package library
+ CommandLine CmdL(Args.data(), _config);
+ if (CmdL.Parse(argc, argv) == false ||
+ pkgInitSystem(*_config, _system) == false)
+ {
+ _error->DumpErrors();
+ return 100;
+ }
+
+ // See if the help should be shown
+ if (_config->FindB("help") == true ||
+ _config->FindB("version") == true ||
+ CmdL.FileSize() == 0)
+ {
+ ShowHelp(CmdL);
+ return 0;
+ }
+
+ // see if we are in simulate mode
+ CheckSimulateMode(CmdL);
+
+ // parse args
+ CmdL.DispatchArg(Cmds);
+
+ // Print any errors or warnings found during parsing
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
+ _error->DumpErrors();
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
+}
+ /*}}}*/
diff --git a/cmdline/makefile b/cmdline/makefile
index 460a71240..e77ad5669 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -5,30 +5,37 @@ SUBDIR=cmdline
# Bring in the default rules
include ../buildlib/defaults.mak
+# The apt program
+PROGRAM=apt
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt.cc
+include $(PROGRAM_H)
+
# The apt-cache program
PROGRAM=apt-cache
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-cache.cc
include $(PROGRAM_H)
# The apt-get program
PROGRAM=apt-get
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-get.cc acqprogress.cc
+SOURCE = apt-get.cc
include $(PROGRAM_H)
# The apt-config program
PROGRAM=apt-config
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-config.cc
include $(PROGRAM_H)
# The apt-cdrom program
PROGRAM=apt-cdrom
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-cdrom.cc
include $(PROGRAM_H)
@@ -41,7 +48,7 @@ include $(COPY_H)
# The apt-mark program
PROGRAM=apt-mark
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-mark.cc
include $(PROGRAM_H)
diff --git a/debian/apt.install b/debian/apt.install.in
index 9d4008fab..ac12060ce 100644
--- a/debian/apt.install
+++ b/debian/apt.install.in
@@ -2,3 +2,4 @@ bin/apt-* usr/bin/
bin/methods/* usr/lib/apt/methods/
scripts/dselect/* usr/lib/dpkg/methods/apt/
usr/share/locale/*/*/apt.mo
+bin/libapt-private.so.* usr/lib/@DEB_HOST_MULTIARCH@/ \ No newline at end of file
diff --git a/debian/apt.lintian-overrides b/debian/apt.lintian-overrides
new file mode 100644
index 000000000..2867c74d9
--- /dev/null
+++ b/debian/apt.lintian-overrides
@@ -0,0 +1,2 @@
+apt: no-shlibs-control-file
+apt: package-name-doesnt-match-sonames
diff --git a/debian/apt.postinst b/debian/apt.postinst
index 9ff1e031c..70de237d0 100644
--- a/debian/apt.postinst
+++ b/debian/apt.postinst
@@ -15,12 +15,16 @@ set -e
case "$1" in
configure)
- SECRING='/etc/apt/secring.gpg'
- # test if secring is an empty normal file
- if test -f $SECRING -a ! -s $SECRING; then
- rm -f $SECRING
+ if dpkg --compare-versions "$2" lt-nl 0.9.9.5; then
+ # we are using tmpfiles for both
+ rm -f /etc/apt/trustdb.gpg
+ # this removal was done unconditional since 0.8.15.3
+ SECRING='/etc/apt/secring.gpg'
+ # test if secring is an empty normal file
+ if test -f $SECRING -a ! -s $SECRING; then
+ rm -f $SECRING
+ fi
fi
- apt-key update
# ensure tighter permissons on the logs, see LP: #975199
if dpkg --compare-versions "$2" lt-nl 0.9.7.7; then
diff --git a/debian/changelog b/debian/changelog
index e2bb9c471..5d3758850 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,93 @@
-apt (0.9.9.5) UNRELEASED; urgency=low
+apt (0.9.11~exp3) UNRELEASEDexperimental; urgency=low
+ * fix incorrect bugnumber for the Pre-Install-Pkgs hook
+
+ -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 19 Aug 2013 15:53:47 +0200
+
+apt (0.9.11~exp2) experimental; urgency=low
+
+ * add lintian override for no-shlibs-control-file so that
+ the internal libapt-private.so.0.0.0 can be shipped
+ * adjust apt.install.in to only install libapt-private.so.*
+
+ -- Michael Vogt <mvo@debian.org> Mon, 19 Aug 2013 14:54:58 +0200
+
+apt (0.9.11~exp1) experimental; urgency=low
+
+ [ Daniel Hartwig ]
+ * Clarify units of Acquire::http::Dl-Limit (closes: #705445)
+ * Show a error message if {,dist-}upgrade is used with additional
+ arguments (closes: #705510)
+
+ [ Michael Vogt ]
+ * lp:~mvo/apt/config-clear:
+ - support Configuration.Clear() for a clear of the entire
+ configuration
+ * lp:~mvo/apt/add-glob-function:
+ - add Glob() to fileutl.{cc,h}
+ * feature/apt-binary2
+ - refactor large chunks of cmdline/*.cc into a new libapt-private
+ library that is shared between the internal apt cmdline tools
+ - install libapt-private* into the apt binary
+ - add PACKAGE_MATCHER_ABI_COMPAT define so that this branch can be
+ merged without breaking ABI
+
+ [ David Kalnischkies ]
+ * ensure that pkgTagFile isn't writing past Buffer length (Closes: 719629)
+ * allow Pre-Install-Pkgs hooks to get info over an FD != stdin
+ (Closes: #671726)
+
+ [ Christian PERRIER ]
+ * French translation update.
+
+ -- Michael Vogt <mvo@debian.org> Mon, 19 Aug 2013 13:25:45 +0200
+
+apt (0.9.10) unstable; urgency=low
+
+ The "Hello to Debconf" upload
+
+ [ Christian Perrier ]
* Vietnamese translation update. Closes: #718615
+ * Japanese translation update. Closes: #719279
+ * French translation update.
+
+ [ Michael Vogt ]
+ * work on fixing coverity scan results:
+ - fix some off-by-one errors
+ - fix some resource leaks
+ - fixes in chroot() handling
+ - fix some missing va_end()
+ * make the code -Wall clean again
+ * remove duplicated #include<list>
+ * add .travis.yml
+ * use the 'abi-complicance-checker' package and remove the buildin
+ copy for the abi checks
+
+ [ David Kalnischkies ]
+ * ensure that FileFd::Size returns 0 in error cases
+ * add missing Turkish (tr) to po/LINGUAS
+ * correct management-typo in description found by lintian
+ * implement debian/rules build-{arch,indep} as required by policy 3.9.4
+ * reenable automatic parallel build of APT
+ * exclude config.{sub,guess} from source package
+ * update the symbol files to reflect current state
+ * unset LANGUAGE for showing [Y/n] answer hints
+ * fix some unitialized data members
+ * specific pins below 1000 cause downgrades (Closes: 543966)
+ * use pkgTagFile to parse "header" of Release files
+ * fix: --print-uris removes authentication (Closes: 719263)
+ * always use our own trustdb.gpg in apt-key
+ * use a tmpfile for trustdb.gpg in apt-key.
+ Thanks to Andreas Beckmann for the initial patch! (Closes: #687611)
+ * do not double-slash paths in apt-key (Closes: 665411)
+ * make the keyring locations in apt-key configurable
+ * let apt-key del work better with softlink and single key keyrings
+ * do not call 'apt-key update' in apt.postinst
+
+ [ Colin Watson ]
+ * prefer native arch over higher priority for providers (Closes: #718482)
- -- Christian Perrier <bubulle@debian.org> Sat, 03 Aug 2013 16:06:55 +0200
+ -- Michael Vogt <mvo@debian.org> Mon, 12 Aug 2013 21:45:07 +0200
apt (0.9.9.4) unstable; urgency=low
diff --git a/debian/rules b/debian/rules
index fc44d5a68..06ccdac31 100755
--- a/debian/rules
+++ b/debian/rules
@@ -115,7 +115,7 @@ clean:
[ ! -f Makefile ] || $(MAKE) clean distclean
rm -rf build
rm -f debian/$(LIBAPT_PKG).install debian/$(LIBAPT_INST).install \
- debian/libapt-pkg-dev.install
+ debian/libapt-pkg-dev.install debian/apt.install
test ! -L buildlib/config.guess || rm -f buildlib/config.guess
test ! -L buildlib/config.sub || rm -f buildlib/config.sub
@@ -174,7 +174,7 @@ apt-doc: build-debiandoc
# Build architecture-dependent files here.
apt_MANPAGES = apt apt-cache apt-cdrom apt-config apt-get apt-key apt-mark apt-secure apt apt.conf apt_preferences sources.list
-apt: build-binary build-manpages
+apt: build-binary build-manpages debian/apt.install
dh_testdir -p$@
dh_testroot -p$@
dh_prep -p$@
diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml
index 9973fe42b..42119baa5 100644
--- a/doc/apt.conf.5.xml
+++ b/doc/apt.conf.5.xml
@@ -386,10 +386,12 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
<para><literal>Acquire::http::AllowRedirect</literal> controls whether APT will follow
redirects, which is enabled by default.</para>
- <para>The used bandwidth can be limited with <literal>Acquire::http::Dl-Limit</literal>
- which accepts integer values in kilobytes. The default value is 0 which deactivates
- the limit and tries to use all available bandwidth (note that this option implicitly
- disables downloading from multiple servers at the same time.)</para>
+ <para>The used bandwidth can be limited with
+ <literal>Acquire::http::Dl-Limit</literal> which accepts integer
+ values in kilobytes per second. The default value is 0 which
+ deactivates the limit and tries to use all available bandwidth.
+ Note that this option implicitly disables downloading from
+ multiple servers at the same time.</para>
<para><literal>Acquire::http::User-Agent</literal> can be used to set a different
User-Agent for the http download method as some proxies allow access for clients
@@ -686,7 +688,8 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
<literal>options</literal> this must be specified in list notation. The commands
are invoked in order using <filename>/bin/sh</filename>; should any fail APT
will abort. APT will pass the filenames of all .deb files it is going to
- install to the commands, one per line on standard input.</para>
+ install to the commands, one per line on the requested file descriptor, defaulting
+ to standard input.</para>
<para>Version 2 of this protocol dumps more information, including the
protocol version, the APT configuration space and the packages, files
@@ -698,7 +701,15 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
<literal>DPkg::Tools::options::<replaceable>cmd</replaceable>::Version</literal>
accordingly, the default being version 1. If APT isn't supporting the requested
version it will send the information in the highest version it has support for instead.
- </para></listitem>
+ </para>
+
+ <para>The file descriptor to be used to send the information can be requested with
+ <literal>DPkg::Tools::options::<replaceable>cmd</replaceable>::InfoFD</literal>
+ which defaults to <literal>0</literal> for standard input and is available since
+ version 0.9.11. Support for the option can be detected by looking for the environment
+ variable <envar>APT_HOOK_INFO_FD</envar> which contains the number of the used
+ file descriptor as a confirmation.</para>
+ </listitem>
</varlistentry>
<varlistentry><term><option>Run-Directory</option></term>
diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc
index 3283128d8..7ecfe78ed 100644
--- a/ftparchive/writer.cc
+++ b/ftparchive/writer.cc
@@ -284,7 +284,8 @@ bool FTWScanner::Delink(string &FileName,const char *OriginalPath,
if (link(FileName.c_str(),OriginalPath) != 0)
{
// Panic! Restore the symlink
- symlink(OldLink,OriginalPath);
+ if (symlink(OldLink,OriginalPath) != 0)
+ _error->Errno("symlink", "failed to restore symlink");
return _error->Errno("link",_("*** Failed to link %s to %s"),
FileName.c_str(),
OriginalPath);
diff --git a/po/fr.po b/po/fr.po
index 9b26539b0..fc6dc4300 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -9,14 +9,14 @@ msgstr ""
"Project-Id-Version: fr\n"
"Report-Msgid-Bugs-To: APT Development Team <deity@lists.debian.org>\n"
"POT-Creation-Date: 2013-07-31 16:24+0200\n"
-"PO-Revision-Date: 2013-04-09 07:58+0200\n"
+"PO-Revision-Date: 2013-08-17 07:57+0200\n"
"Last-Translator: Christian Perrier <bubulle@debian.org>\n"
"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 1.4\n"
+"X-Generator: Lokalize 1.5\n"
"Plural-Forms: Plural-Forms: nplurals=2; plural=n > 1;\n"
#: cmdline/apt-cache.cc:158
@@ -243,6 +243,10 @@ msgid ""
"You may try the --cdrom option to set the CD-ROM mount point. See 'man apt-"
"cdrom' for more information about the CD-ROM auto-detection and mount point."
msgstr ""
+"Aucun CD n'a été détecté sur le point de montage par défaut.\n"
+"Vous pouvez utiliser l'option --cdrom pour indiquer le point de montage du "
+"CD-ROM. Voir la page de manuel d'apt-cdrom pour plus d'informations sur "
+"l'auto-détection des CD et le point de montage."
#: cmdline/apt-cdrom.cc:85
msgid "Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'"
@@ -1606,6 +1610,8 @@ msgid ""
"Clearsigned file isn't valid, got '%s' (does the network require "
"authentication?)"
msgstr ""
+"Le fichier signé en clair n'est pas valable, ce qui a été reçu est « %s ». "
+"Peut-être le réseau nécessite-t-il une authentification."
#: methods/gpgv.cc:183
msgid "Unknown error executing gpgv"
@@ -1729,9 +1735,9 @@ msgid "Can not read mirror file '%s'"
msgstr "Impossible de lire le fichier de miroir « %s »."
#: methods/mirror.cc:315
-#, fuzzy, c-format
+#, c-format
msgid "No entry found in mirror file '%s'"
-msgstr "Impossible de lire le fichier de miroir « %s »."
+msgstr "Pas d'entrée trouvée dans le fichier de miroir « %s »."
#: methods/mirror.cc:445
#, c-format
diff --git a/po/ja.po b/po/ja.po
index 724dd3000..97c476b09 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -6,10 +6,10 @@
# Debian Project, Kenshi Muto <kmuto@debian.org>, 2004-2012
msgid ""
msgstr ""
-"Project-Id-Version: apt 0.9.7.1\n"
+"Project-Id-Version: apt 0.9.9.4\n"
"Report-Msgid-Bugs-To: APT Development Team <deity@lists.debian.org>\n"
"POT-Creation-Date: 2013-07-31 16:24+0200\n"
-"PO-Revision-Date: 2012-07-01 00:14+0900\n"
+"PO-Revision-Date: 2013-08-11 19:39+0900\n"
"Last-Translator: Kenshi Muto <kmuto@debian.org>\n"
"Language-Team: Debian Japanese List <debian-japanese@lists.debian.org>\n"
"Language: ja\n"
@@ -239,6 +239,10 @@ msgid ""
"You may try the --cdrom option to set the CD-ROM mount point. See 'man apt-"
"cdrom' for more information about the CD-ROM auto-detection and mount point."
msgstr ""
+"CD-ROM が自動検出されなかったか、デフォルトで利用するマウントポイントに見当た"
+"りませんでした。CD-ROM のマウントポイントを設定するために --cdrom オプション"
+"を試すことができます。CD-ROM の自動検出およびマウントポイントの詳細について"
+"は、'man apt-cdrom' を参照してください。"
#: cmdline/apt-cdrom.cc:85
msgid "Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'"
@@ -570,7 +574,7 @@ msgstr "検証なしにこれらのパッケージをインストールします
#: cmdline/apt-get.cc:1110
msgid "Some packages could not be authenticated"
-msgstr "いくつかのパッケージを認証できませんでした?"
+msgstr "いくつかのパッケージを認証できませんでした"
#: cmdline/apt-get.cc:1119 cmdline/apt-get.cc:1280
msgid "There are problems and -y was used without --force-yes"
@@ -659,7 +663,7 @@ msgstr "中断しました。"
#: cmdline/apt-get.cc:1313
msgid "Do you want to continue?"
-msgstr "続行しますか"
+msgstr "続行しますか?"
#: cmdline/apt-get.cc:1385 cmdline/apt-get.cc:2686 apt-pkg/algorithms.cc:1566
#, c-format
@@ -1526,9 +1530,9 @@ msgid "Temporary failure resolving '%s'"
msgstr "'%s' が一時的に解決できません"
#: methods/connect.cc:209
-#, fuzzy, c-format
+#, c-format
msgid "System error resolving '%s:%s'"
-msgstr "'%s:%s' (%i - %s) の解決中に何か問題が起こりました"
+msgstr "'%s:%s' の解決中にシステムエラーが発生しました"
#: methods/connect.cc:211
#, c-format
@@ -1562,6 +1566,8 @@ msgid ""
"Clearsigned file isn't valid, got '%s' (does the network require "
"authentication?)"
msgstr ""
+"クリアサインされたファイルが有効ではなく、'%s' を得ました (認証にネットワーク"
+"が必要?)"
#: methods/gpgv.cc:183
msgid "Unknown error executing gpgv"
@@ -1683,9 +1689,9 @@ msgid "Can not read mirror file '%s'"
msgstr "ミラーファイル '%s' を読み込めません"
#: methods/mirror.cc:315
-#, fuzzy, c-format
+#, c-format
msgid "No entry found in mirror file '%s'"
-msgstr "ミラーファイル '%s' を読み込めません"
+msgstr "ミラーファイル '%s' のエントリが見つかりません"
#: methods/mirror.cc:445
#, c-format
@@ -2466,13 +2472,13 @@ msgstr "%c%s... 完了"
#: apt-pkg/contrib/progress.cc:179
msgid "..."
-msgstr ""
+msgstr "..."
#. Print the spinner
#: apt-pkg/contrib/progress.cc:195
-#, fuzzy, c-format
+#, c-format
msgid "%c%s... %u%%"
-msgstr "%c%s... 完了"
+msgstr "%c%s... %u%%"
#: apt-pkg/contrib/cmndline.cc:80
#, c-format
@@ -3541,9 +3547,3 @@ msgstr ""
#: apt-pkg/deb/debsystem.cc:121
msgid "Not locked"
msgstr "ロックされていません"
-
-#~ msgid "File %s doesn't start with a clearsigned message"
-#~ msgstr "ファイル %s はクリア署名されたメッセージで始まっていません"
-
-#~ msgid "Skipping nonexistent file %s"
-#~ msgstr "存在しないファイル %s をスキップしています"
diff --git a/test/integration/framework b/test/integration/framework
index 7dd7c20a7..54d35fef8 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -88,11 +88,11 @@ msgdone() {
runapt() {
msgdebug "Executing: ${CCMD}$*${CDEBUG} "
if [ -f ./aptconfig.conf ]; then
- APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
- elif [ -f ../aptconfig.conf ]; then
- APT_CONFIG=../aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
+ MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
+ elif [ -f ../aptconfig.conf ]; then
+ MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG=../aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
else
- LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
+ MALLOC_PERTURB_=21 MALLOC_CHECK_=2 LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$*
fi
}
aptconfig() { runapt apt-config $*; }
@@ -131,13 +131,23 @@ exitwithstatus() {
exit $((EXIT_CODE <= 255 ? EXIT_CODE : 255));
}
+shellsetedetector() {
+ local exit_status=$?
+ if [ "$exit_status" != '0' ]; then
+ echo >&2 "${CERROR}E: Looks like the testcases ended prematurely with exitcode: ${exit_status}${CNORMAL}"
+ if [ "$EXIT_CODE" = '0' ]; then
+ EXIT_CODE="$exit_status"
+ fi
+ fi
+}
+
addtrap() {
if [ "$1" = 'prefix' ]; then
CURRENTTRAP="$2 $CURRENTTRAP"
else
CURRENTTRAP="$CURRENTTRAP $1"
fi
- trap "$CURRENTTRAP exitwithstatus;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+ trap "shellsetedetector; $CURRENTTRAP exitwithstatus;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
}
setupenvironment() {
@@ -177,7 +187,7 @@ setupenvironment() {
echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf
echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf
echo "DPKG::options:: \"--force-bad-path\";" >> aptconfig.conf
- if ! $(which dpkg) --assert-multi-arch 2>&1 > /dev/null; then
+ if ! $(which dpkg) --assert-multi-arch >/dev/null 2>&1; then
echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it…
fi
echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf
@@ -225,7 +235,7 @@ configdpkg() {
echo -n > rootdir/var/lib/dpkg/status
fi
fi
- if $(which dpkg) --assert-multi-arch 2>&1 > /dev/null; then
+ if $(which dpkg) --assert-multi-arch >/dev/null 2>&1; then
local ARCHS="$(getarchitectures)"
if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
DPKGARCH="$(dpkg --print-architecture)"
@@ -711,22 +721,45 @@ setupaptarchive() {
signreleasefiles() {
local SIGNER="${1:-Joe Sixpack}"
+ local GPG="gpg --batch --yes --no-default-keyring --trustdb-name rootdir/etc/apt/trustdb.gpg"
msgninfo "\tSign archive with $SIGNER key… "
- local SECKEYS=""
+ local REXKEY='keys/rexexpired'
+ local SECEXPIREBAK="${REXKEY}.sec.bak"
+ local PUBEXPIREBAK="${REXKEY}.pub.bak"
+ if [ "${SIGNER}" = 'Rex Expired' ]; then
+ # the key is expired, so gpg doesn't allow to sign with and the --faked-system-time
+ # option doesn't exist anymore (and using faketime would add a new obscure dependency)
+ # therefore we 'temporary' make the key not expired and restore a backup after signing
+ cp ${REXKEY}.sec $SECEXPIREBAK
+ cp ${REXKEY}.pub $PUBEXPIREBAK
+ local SECUNEXPIRED="${REXKEY}.sec.unexpired"
+ local PUBUNEXPIRED="${REXKEY}.pub.unexpired"
+ if [ -f "$SECUNEXPIRED" ] && [ -f "$PUBUNEXPIRED" ]; then
+ cp $SECUNEXPIRED ${REXKEY}.sec
+ cp $PUBUNEXPIRED ${REXKEY}.pub
+ else
+ printf "expire\n1w\nsave\n" | $GPG --keyring ${REXKEY}.pub --secret-keyring ${REXKEY}.sec --command-fd 0 --edit-key "${SIGNER}" >/dev/null 2>&1 || true
+ cp ${REXKEY}.sec $SECUNEXPIRED
+ cp ${REXKEY}.pub $PUBUNEXPIRED
+ fi
+ fi
for KEY in $(find keys/ -name '*.sec'); do
- SECKEYS="$SECKEYS --secret-keyring $KEY"
+ GPG="$GPG --secret-keyring $KEY"
done
- local PUBKEYS=""
for KEY in $(find keys/ -name '*.pub'); do
- PUBKEYS="$PUBKEYS --keyring $KEY"
+ GPG="$GPG --keyring $KEY"
done
for RELEASE in $(find aptarchive/ -name Release); do
- gpg --yes --no-default-keyring $SECKEYS $PUBKEYS --default-key "$SIGNER" -abs -o ${RELEASE}.gpg ${RELEASE}
+ $GPG --default-key "$SIGNER" --armor --detach-sign --sign --output ${RELEASE}.gpg ${RELEASE}
local INRELEASE="$(echo "${RELEASE}" | sed 's#/Release$#/InRelease#')"
- gpg --yes --no-default-keyring $SECKEYS $PUBKEYS --default-key "$SIGNER" --clearsign -o $INRELEASE $RELEASE
+ $GPG --default-key "$SIGNER" --clearsign --output $INRELEASE $RELEASE
# we might have set a specific date for the Release file, so copy it
touch -d "$(stat --format "%y" ${RELEASE})" ${RELEASE}.gpg ${INRELEASE}
done
+ if [ -f "$SECEXPIREBAK" ] && [ -f "$PUBEXPIREBAK" ]; then
+ mv -f $SECEXPIREBAK ${REXKEY}.sec
+ mv -f $PUBEXPIREBAK ${REXKEY}.pub
+ fi
msgdone "info"
}
@@ -828,7 +861,7 @@ testequalor2() {
echo "$2" > $COMPAREFILE2
shift 2
msgtest "Test for equality OR of" "$*"
- $* 2>&1 1> $COMPAREAGAINST
+ $* >$COMPAREAGAINST 2>&1
(checkdiff $COMPAREFILE1 $COMPAREAGAINST 1> /dev/null ||
checkdiff $COMPAREFILE2 $COMPAREAGAINST 1> /dev/null) && msgpass ||
( echo "\n${CINFO}Diff against OR 1${CNORMAL}" "$(checkdiff $COMPAREFILE1 $COMPAREAGAINST)" \
@@ -905,6 +938,40 @@ testmarkedauto() {
aptmark showauto 2>&1 | checkdiff $COMPAREFILE - && msgpass || msgfail
}
+testsuccess() {
+ if [ "$1" = '--nomsg' ]; then
+ shift
+ else
+ msgtest 'Test for successful execution of' "$*"
+ fi
+ local OUTPUT=$(mktemp)
+ addtrap "rm $OUTPUT;"
+ if $@ >${OUTPUT} 2>&1; then
+ msgpass
+ else
+ echo
+ cat $OUTPUT
+ msgfail
+ fi
+}
+
+testfailure() {
+ if [ "$1" = '--nomsg' ]; then
+ shift
+ else
+ msgtest 'Test for failure in execution of' "$*"
+ fi
+ local OUTPUT=$(mktemp)
+ addtrap "rm $OUTPUT;"
+ if $@ >${OUTPUT} 2>&1; then
+ echo
+ cat $OUTPUT
+ msgfail
+ else
+ msgpass
+ fi
+}
+
pause() {
echo "STOPPED execution. Press enter to continue"
local IGNORE
diff --git a/test/integration/rexexpired.pub b/test/integration/rexexpired.pub
new file mode 100644
index 000000000..5ab2e489a
--- /dev/null
+++ b/test/integration/rexexpired.pub
Binary files differ
diff --git a/test/integration/rexexpired.sec b/test/integration/rexexpired.sec
new file mode 100644
index 000000000..dc00168cd
--- /dev/null
+++ b/test/integration/rexexpired.sec
Binary files differ
diff --git a/test/integration/skip-avoid-avoiding-breaks-predepends b/test/integration/skip-avoid-avoiding-breaks-predepends
index a47e8bc2b..ed231bc3f 100755
--- a/test/integration/skip-avoid-avoiding-breaks-predepends
+++ b/test/integration/skip-avoid-avoiding-breaks-predepends
@@ -17,5 +17,5 @@ Pre-Depends: looping (>= 1.15)'
setupaptarchive
-aptget dist-upgrade -y -o Debug::pkgOrderList=1 #-qq 2>&1 > /dev/null
+aptget dist-upgrade -y -o Debug::pkgOrderList=1 #-qq >/dev/null 2>&1
testdpkginstalled looping loop1 loop2
diff --git a/test/integration/test-apt-cdrom b/test/integration/test-apt-cdrom
index 6e3533152..85c3a2fee 100755
--- a/test/integration/test-apt-cdrom
+++ b/test/integration/test-apt-cdrom
@@ -102,5 +102,5 @@ aptcache show testing -o Acquire::Languages=en | grep -q '^Description-en: ' &&
# check that we really can install from a 'cdrom'
testdpkgnotinstalled testing
-aptget install testing -y > /dev/null 2>&1
+testsuccess aptget install testing -y
testdpkginstalled testing
diff --git a/test/integration/test-apt-get-autoremove b/test/integration/test-apt-get-autoremove
index c25ce3f58..dc30cde34 100755
--- a/test/integration/test-apt-get-autoremove
+++ b/test/integration/test-apt-get-autoremove
@@ -11,11 +11,11 @@ buildsimplenativepackage 'po-debconf' 'all' '1.0.16' 'unstable'
buildsimplenativepackage 'debhelper' 'all' '8.0.0' 'unstable' 'Depends: po-debconf'
setupaptarchive
-aptget install unrelated debhelper -qq 2>&1 > /dev/null
+testsuccess aptget install unrelated debhelper -y
testdpkginstalled 'unrelated' 'debhelper' 'po-debconf'
testmarkedauto 'po-debconf'
-aptget remove debhelper -y -qq 2>&1 > /dev/null
+testsuccess aptget remove debhelper -y
testdpkgnotinstalled 'debhelper'
testdpkginstalled 'po-debconf' 'unrelated'
@@ -30,15 +30,15 @@ Remv po-debconf [1.0.16]' aptget autoremove -s
testdpkginstalled 'po-debconf'
echo 'APT::NeverAutoRemove { "^po-debconf$"; };' > rootdir/etc/apt/apt.conf.d/00autoremove
-aptget autoremove -y -qq 2>&1 > /dev/null
+testsuccess aptget autoremove -y
testdpkginstalled 'po-debconf'
echo 'APT::NeverAutoRemove { "^po-.*$"; };' > rootdir/etc/apt/apt.conf.d/00autoremove
-aptget autoremove -y -qq 2>&1 > /dev/null
+testsuccess aptget autoremove -y
testdpkginstalled "po-debconf"
rm rootdir/etc/apt/apt.conf.d/00autoremove
-aptget autoremove -y -qq 2>&1 > /dev/null
+testsuccess aptget autoremove -y
testdpkgnotinstalled 'po-debconf'
testmarkedauto
diff --git a/test/integration/test-apt-key b/test/integration/test-apt-key
new file mode 100755
index 000000000..68b3f9710
--- /dev/null
+++ b/test/integration/test-apt-key
@@ -0,0 +1,107 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'amd64'
+
+msgtest 'Check that paths in list output are not' 'double-slashed'
+aptkey list 2>&1 | grep -q '//' && msgfail || msgpass
+
+msgtest 'Check that paths in finger output are not' 'double-slashed'
+aptkey finger 2>&1 | grep -q '//' && msgfail || msgpass
+
+echo 'APT::Key::ArchiveKeyring "./keys/joesixpack.pub";
+APT::Key::RemovedKeys "./keys/rexexpired.pub";' > rootdir/etc/apt/apt.conf.d/aptkey.conf
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/DBAC8DAE 2010-08-18'
+
+testequal 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed
+gpg: Total number processed: 1
+gpg: unchanged: 1' aptkey --fakeroot update
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/DBAC8DAE 2010-08-18'
+
+testsuccess aptkey --fakeroot add ./keys/rexexpired.pub
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]
+pub 2048R/DBAC8DAE 2010-08-18'
+
+msgtest 'Execute update again to trigger removal of' 'Rex Expired key'
+testsuccess --nomsg aptkey --fakeroot update
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/DBAC8DAE 2010-08-18'
+
+msgtest "Try to remove a key which exists, but isn't in the" 'forced keyring'
+testsuccess --nomsg aptkey --fakeroot --keyring rootdir/etc/apt/trusted.gpg del DBAC8DAE
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/DBAC8DAE 2010-08-18'
+
+testsuccess aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+
+# start from a clean plate again
+cleanplate() {
+ rm -rf rootdir/etc/apt/trusted.gpg.d/ rootdir/etc/apt/trusted.gpg
+ mkdir rootdir/etc/apt/trusted.gpg.d/
+}
+
+msgtest 'Test key removal with' 'single key in real file'
+cleanplate
+cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+
+msgtest 'Test key removal with' 'single key in softlink'
+cleanplate
+ln -s $(readlink -f ./keys/joesixpack.pub) rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess test -L rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+
+cleanplate
+testsuccess aptkey --fakeroot add ./keys/joesixpack.pub
+testsuccess aptkey --fakeroot add ./keys/marvinparanoid.pub
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/DBAC8DAE 2010-08-18
+pub 2048R/528144E2 2011-01-16'
+cp -a rootdir/etc/apt/trusted.gpg keys/testcase-multikey.pub # store for reuse
+
+msgtest 'Test key removal with' 'multi key in real file'
+cleanplate
+cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/528144E2 2011-01-16'
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+
+msgtest 'Test key removal with' 'multi key in softlink'
+cleanplate
+ln -s $(readlink -f ./keys/testcase-multikey.pub) rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/528144E2 2011-01-16'
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+testsuccess test ! -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess test -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+
+msgtest 'Test key removal with' 'multiple files including key'
+cleanplate
+cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub 2048R/528144E2 2011-01-16'
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
diff --git a/test/integration/test-bug-407511-fail-invalid-default-release b/test/integration/test-bug-407511-fail-invalid-default-release
index 7f23a1e82..3d3b0ada3 100755
--- a/test/integration/test-bug-407511-fail-invalid-default-release
+++ b/test/integration/test-bug-407511-fail-invalid-default-release
@@ -35,14 +35,14 @@ setupaptarchive
passdist() {
msgtest 'Test that target-release is accepted' $1
- aptget dist-upgrade -t $1 -qq && msgpass || msgfail
+ testsuccess --nomsg aptget dist-upgrade -t $1
msgtest 'Test that target-release pins with' $1
aptcache policy -t $1 | grep -q ' 990' && msgpass || msgfail
}
faildist() {
msgtest 'Test that target-release is refused' $1
- aptget dist-upgrade -t $1 -qq 2> /dev/null && msgfail || msgpass
+ testfailure --nomsg aptget dist-upgrade -t $1
}
msgtest 'Test that no default-release is active in this test' 'setup'
diff --git a/test/integration/test-bug-507998-dist-upgrade-recommends b/test/integration/test-bug-507998-dist-upgrade-recommends
new file mode 100755
index 000000000..513421a94
--- /dev/null
+++ b/test/integration/test-bug-507998-dist-upgrade-recommends
@@ -0,0 +1,25 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64'
+
+insertinstalledpackage 'tshark' 'amd64' '1.0.4-1' 'Depends: wireshark-common'
+insertinstalledpackage 'wireshark-common' 'amd64' '1.0.4-1' 'Recommends: wireshark (>= 1.0.4-1) | tshark (>= 1.0.4-1)'
+insertpackage 'unstable' 'tshark' 'amd64' '1.2.1-2' 'Depends: wireshark-common (= 1.2.1-2)'
+insertpackage 'unstable' 'wireshark-common' 'amd64' '1.2.1-2' 'Recommends: wireshark (>= 1.2.1-2) | tshark (>= 1.2.1-2)'
+insertpackage 'unstable' 'wireshark' 'amd64' '1.2.1-2' 'Depends: wireshark-common (= 1.2.1-2)'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be upgraded:
+ tshark wireshark-common
+2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
+Inst wireshark-common [1.0.4-1] (1.2.1-2 unstable [amd64])
+Inst tshark [1.0.4-1] (1.2.1-2 unstable [amd64])
+Conf wireshark-common (1.2.1-2 unstable [amd64])
+Conf tshark (1.2.1-2 unstable [amd64])' aptget dist-upgrade -s
diff --git a/test/integration/test-bug-543966-downgrade-below-1000-pin b/test/integration/test-bug-543966-downgrade-below-1000-pin
new file mode 100755
index 000000000..f602bea95
--- /dev/null
+++ b/test/integration/test-bug-543966-downgrade-below-1000-pin
@@ -0,0 +1,81 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'i386'
+
+insertpackage 'unstable' 'base-files' 'all' '5.0.0'
+insertinstalledpackage 'base-files' 'all' '5.0.0-1'
+
+setupaptarchive
+
+STATUS=$(readlink -f rootdir/var/lib/dpkg/status)
+APTARCHIVE="$(readlink -f aptarchive)/"
+
+testequal "base-files:
+ Installed: 5.0.0-1
+ Candidate: 5.0.0-1
+ Version table:
+ *** 5.0.0-1 0
+ 100 $STATUS
+ 5.0.0 0
+ 500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=0
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 99' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+ Installed: 5.0.0-1
+ Candidate: 5.0.0-1
+ Package pin: 5.0.0
+ Version table:
+ *** 5.0.0-1 99
+ 100 $STATUS
+ 5.0.0 99
+ 500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=99
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 100' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+ Installed: 5.0.0-1
+ Candidate: 5.0.0-1
+ Package pin: 5.0.0
+ Version table:
+ *** 5.0.0-1 100
+ 100 $STATUS
+ 5.0.0 100
+ 500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=100
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 999' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+ Installed: 5.0.0-1
+ Candidate: 5.0.0-1
+ Package pin: 5.0.0
+ Version table:
+ *** 5.0.0-1 999
+ 100 $STATUS
+ 5.0.0 999
+ 500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=999
+
+echo 'Package: base-files
+Pin: release a=unstable
+Pin-Priority: 1000' > rootdir/etc/apt/preferences
+
+testequal "base-files:
+ Installed: 5.0.0-1
+ Candidate: 5.0.0
+ Package pin: 5.0.0
+ Version table:
+ *** 5.0.0-1 1000
+ 100 $STATUS
+ 5.0.0 1000
+ 500 file:${APTARCHIVE} unstable/main i386 Packages" aptcache policy base-files -o apt::pin=1000
diff --git a/test/integration/test-bug-602412-dequote-redirect b/test/integration/test-bug-602412-dequote-redirect
index c20443559..bcebb57b8 100755
--- a/test/integration/test-bug-602412-dequote-redirect
+++ b/test/integration/test-bug-602412-dequote-redirect
@@ -16,7 +16,7 @@ mv aptarchive/pool aptarchive/newpool
mv aptarchive/dists aptarchive/newdists
msgtest 'Test redirection works in' 'apt-get update'
-aptget update -qq && msgpass || msgfail
+testsuccess --nomsg aptget update
# check that I-M-S header is kept in redirections
testequal 'Hit http://localhost:8080 unstable InRelease
@@ -26,4 +26,4 @@ Hit http://localhost:8080 unstable/main Translation-en
Reading package lists...' aptget update #-o debug::pkgacquire=1 -o debug::pkgacquire::worker=1
msgtest 'Test redirection works in' 'package download'
-aptget install unrelated --download-only -qq && msgpass || msgfail
+testsuccess --nomsg aptget install unrelated --download-only -y
diff --git a/test/integration/test-bug-604222-new-and-autoremove b/test/integration/test-bug-604222-new-and-autoremove
index ea73c5775..b29347f64 100755
--- a/test/integration/test-bug-604222-new-and-autoremove
+++ b/test/integration/test-bug-604222-new-and-autoremove
@@ -8,7 +8,7 @@ configarchitecture "i386"
setupaptarchive
touch rootdir/var/lib/apt/extended_states
-aptmark markauto 'libvtk5.4'
+testsuccess aptmark markauto 'libvtk5.4'
testmarkedauto 'libvtk5.4'
testequal "Reading package lists...
diff --git a/test/integration/test-bug-604401-files-are-directories b/test/integration/test-bug-604401-files-are-directories
index aae717a19..e6913edcf 100755
--- a/test/integration/test-bug-604401-files-are-directories
+++ b/test/integration/test-bug-604401-files-are-directories
@@ -11,7 +11,7 @@ test ! -e rootdir/etc/apt/apt.conf || mv rootdir/etc/apt/apt.conf rootdir/etc/ap
msgtest "Directory instead of a file as apt.conf ignored"
mkdir -p rootdir/etc/apt/apt.conf
-aptconfig dump > /dev/null && msgpass || msgfail
+testsuccess --nomsg aptconfig dump
rmdir rootdir/etc/apt/apt.conf
msgtest "Good link instead of a file as apt.conf ignored"
@@ -22,7 +22,7 @@ rm rootdir/etc/apt/apt.conf
msgtest "Broken link instead of a file as apt.conf ignored"
ln -s /tmp/doesnt-exist rootdir/etc/apt/apt.conf
-aptconfig dump > /dev/null && msgpass || msgfail
+testsuccess --nomsg aptconfig dump
rm rootdir/etc/apt/apt.conf
@@ -30,7 +30,7 @@ test ! -e rootdir/etc/apt/sources.list || mv rootdir/etc/apt/sources.list rootdi
msgtest "Directory instead of a file as sources.list ignored"
mkdir -p rootdir/etc/apt/sources.list
-aptget update --print-uris 2> /dev/null && msgpass || msgfail
+testsuccess --nomsg aptget update --print-uris
rmdir rootdir/etc/apt/sources.list
msgtest "Good link instead of a file as sources.list ignored"
@@ -49,7 +49,7 @@ test ! -e rootdir/etc/apt/preferences || mv rootdir/etc/apt/preferences rootdir/
msgtest "Directory instead of a file as preferences ignored"
mkdir -p rootdir/etc/apt/preferences
-aptcache policy > /dev/null 2> /dev/null && msgpass || msgfail
+testsuccess --nomsg aptcache policy
rmdir rootdir/etc/apt/preferences
msgtest "Good link instead of a file as preferences ignored"
@@ -62,5 +62,5 @@ rm rootdir/etc/apt/preferences
msgtest "Broken link instead of a file as preferences ignored"
ln -s /tmp/doesnt-exist rootdir/etc/apt/preferences
-aptcache policy > /dev/null 2> /dev/null && msgpass || msgfail
+testsuccess --nomsg aptcache policy
rm rootdir/etc/apt/preferences
diff --git a/test/integration/test-bug-611729-mark-as-manual b/test/integration/test-bug-611729-mark-as-manual
index 9cf01610c..e3d454f97 100755
--- a/test/integration/test-bug-611729-mark-as-manual
+++ b/test/integration/test-bug-611729-mark-as-manual
@@ -15,21 +15,21 @@ buildsimplenativepackage "c" "all" "1.0" "stable" "Depends: b"
setupaptarchive
# dpkg freaks out if the last package is removed so keep one around
-aptget install peace-dpkg -y -qq 2>&1 > /dev/null
+testsuccess aptget install peace-dpkg -y
testdpkginstalled peace-dpkg
testmarkedauto
-aptget install a -y -qq 2>&1 > /dev/null
+testsuccess aptget install a -y
testdpkginstalled a b
testdpkgnotinstalled c
testmarkedauto 'b'
-aptget remove a -y -qq 2>&1 > /dev/null
+testsuccess aptget remove a -y
testdpkgnotinstalled a c
testdpkginstalled b
testmarkedauto 'b'
-aptget install c -y -qq 2>&1 > /dev/null
+testsuccess aptget install c -y
testdpkgnotinstalled a
testdpkginstalled b c
testmarkedauto 'b'
@@ -50,7 +50,7 @@ testmarkedauto 'b'
rm rootdir/var/log/apt/history.log
-aptget install b --reinstall -y -qq 2>&1 > /dev/null
+testsuccess aptget install b --reinstall -y
testdpkgnotinstalled a
testdpkginstalled b c
testmarkedauto 'b'
@@ -67,24 +67,24 @@ b set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget install b
testmarkedauto
-aptget remove b -y -qq 2>&1 > /dev/null
+testsuccess aptget remove b -y
testdpkgnotinstalled a b c
testmarkedauto
-aptget install a b -y -qq 2>&1 > /dev/null
+testsuccess aptget install a b -y
testdpkginstalled a b
testdpkgnotinstalled c
testmarkedauto
-aptget purge a b -y -qq 2>&1 > /dev/null
+testsuccess aptget purge a b -y
testdpkgnotinstalled a b c
testmarkedauto
-aptget install b c -y -qq 2>&1 > /dev/null
+testsuccess aptget install b c -y
testdpkgnotinstalled a
testdpkginstalled b c
testmarkedauto
-aptget install a -y -qq 2>&1 > /dev/null
+testsuccess aptget install a -y
testdpkginstalled a b c
testmarkedauto
diff --git a/test/integration/test-bug-612099-multiarch-conflicts b/test/integration/test-bug-612099-multiarch-conflicts
index 530012e5d..20dc3a7e5 100755
--- a/test/integration/test-bug-612099-multiarch-conflicts
+++ b/test/integration/test-bug-612099-multiarch-conflicts
@@ -15,7 +15,7 @@ buildsimplenativepackage 'foobar' 'amd64' '1.0' 'stable' 'Depends: libc6'
setupaptarchive
-aptget install libc6:i386 -t stable -y -qq 2>&1 > /dev/null
+testsuccess aptget install libc6:i386 -t stable -y
testdpkginstalled libc6:i386
testequal 'Reading package lists...
Building dependency tree...
@@ -78,9 +78,9 @@ Conf libc6 (2.0 testing [all])' aptget upgrade -t testing -s
# FIXME: on amd64 systems this test wouldn't run with a real upgrade
# as APT (here i386) disagree about the native architecture, so
# we fake it here:
-#aptget upgrade -y -qq 2>&1 > /dev/null
-aptget purge libc6 -y -qq 2>&1 >/dev/null
-aptget install libc6:i386 -y -qq 2>&1 >/dev/null
+#aptget upgrade -y -qq >/dev/null 2>&1
+testsuccess aptget purge libc6 -y
+testsuccess aptget install libc6:i386 -y
testdpkginstalled libc6:all
testequal 'Reading package lists...
@@ -129,7 +129,7 @@ buildsimplenativepackage 'foobar-same' 'amd64' '1.0' 'stable' 'Depends: libc6-sa
setupaptarchive
-aptget install libc6-same:i386 -t stable -y -qq 2>&1 > /dev/null
+testsuccess aptget install libc6-same:i386 -t stable -y
testdpkginstalled libc6-same:i386
testequal 'Reading package lists...
@@ -176,9 +176,9 @@ Conf libc6-same (2.0 testing [all])' aptget upgrade -t testing -s
# FIXME: on amd64 systems this test wouldn't run with a real upgrade
# as APT (here i386) disagree about the native architecture, so
# we fake it here:
-#aptget upgrade -y -qq 2>&1 > /dev/null
-aptget purge libc6-same -y -qq 2>&1 >/dev/null
-aptget install libc6-same:i386 -y -qq 2>&1 >/dev/null
+#aptget upgrade -y -qq >/dev/null 2>&1
+testsuccess aptget purge libc6-same -y
+testsuccess aptget install libc6-same:i386 -y
testdpkginstalled libc6-same:all
diff --git a/test/integration/test-bug-612557-garbage-upgrade b/test/integration/test-bug-612557-garbage-upgrade
index 8efd1687a..910b3b149 100755
--- a/test/integration/test-bug-612557-garbage-upgrade
+++ b/test/integration/test-bug-612557-garbage-upgrade
@@ -13,7 +13,7 @@ insertpackage 'unstable' 'libreoffice-common' 'all' '1:3.3.0-2' 'Conflicts: open
setupaptarchive
touch rootdir/var/lib/apt/extended_states
-aptmark markauto python-uno openoffice.org-common
+testsuccess aptmark markauto python-uno openoffice.org-common
#aptmark unmarkauto openoffice.org-emailmerge
testmarkedauto python-uno openoffice.org-common
@@ -32,7 +32,7 @@ The following packages will be upgraded:
After this operation, 53.2 MB disk space will be freed.
E: Trivial Only specified but this is not a trivial operation.' aptget --trivial-only install python-uno
-aptmark markauto openoffice.org-emailmerge
+testsuccess aptmark markauto openoffice.org-emailmerge
testmarkedauto python-uno openoffice.org-common openoffice.org-emailmerge
testequal 'Reading package lists...
diff --git a/test/integration/test-bug-612958-use-dpkg-multiarch-config b/test/integration/test-bug-612958-use-dpkg-multiarch-config
index 18b964636..4d1f00ca0 100755
--- a/test/integration/test-bug-612958-use-dpkg-multiarch-config
+++ b/test/integration/test-bug-612958-use-dpkg-multiarch-config
@@ -14,13 +14,13 @@ insertinstalledpackage 'libapt' 'armel' '1.0'
testpass() {
rm rootdir/var/cache/apt/*.bin
msgtest 'Test architecture handling' "$1 with $2"
- aptcache show libapt:$2 2> /dev/null > /dev/null && msgpass || msgfail
+ testsuccess --nomsg aptcache show libapt:$2
}
testfail() {
rm rootdir/var/cache/apt/*.bin
msgtest 'Test architecture handling' "$1 with $2"
- aptcache show libapt:$2 2> /dev/null > /dev/null && msgfail || msgpass
+ testfailure --nomsg aptcache show libapt:$2
}
testpass 'no config' 'i386'
diff --git a/test/integration/test-bug-613420-new-garbage-dependency b/test/integration/test-bug-613420-new-garbage-dependency
index 7a08871ca..9d9f1096a 100755
--- a/test/integration/test-bug-613420-new-garbage-dependency
+++ b/test/integration/test-bug-613420-new-garbage-dependency
@@ -15,7 +15,7 @@ insertpackage 'unstable' 'openoffice.org-officebean' 'all' '1:3.3.0-5' 'Depends:
setupaptarchive
touch rootdir/var/lib/apt/extended_states
-aptmark markauto openoffice.org-officebean
+testsuccess aptmark markauto openoffice.org-officebean
testmarkedauto openoffice.org-officebean
testequal "Reading package lists...
diff --git a/test/integration/test-bug-618288-multiarch-same-lockstep b/test/integration/test-bug-618288-multiarch-same-lockstep
index fde075172..e0305b64b 100755
--- a/test/integration/test-bug-618288-multiarch-same-lockstep
+++ b/test/integration/test-bug-618288-multiarch-same-lockstep
@@ -16,7 +16,7 @@ buildsimplenativepackage 'apt' 'i386' '2' 'unstable' 'Depends: libsame (= 2)' ''
buildsimplenativepackage 'apt2' 'amd64' '2' 'unstable' 'Depends: libsame (= 2)' '' 'required'
setupaptarchive
-aptget dist-upgrade -s 2>&1 > output.apt
+aptget dist-upgrade -s >output.apt 2>&1
# order in switch libsame:{amd64,i386} are unpacked is irrelevant, as both are installed - but we need to do it together
LS_U_AMD="$(grep -o -n '^Inst libsame ' output.apt | cut -d: -f1)"
diff --git a/test/integration/test-bug-64141-install-dependencies-for-on-hold b/test/integration/test-bug-64141-install-dependencies-for-on-hold
index e2d206fdd..9a9e7be10 100755
--- a/test/integration/test-bug-64141-install-dependencies-for-on-hold
+++ b/test/integration/test-bug-64141-install-dependencies-for-on-hold
@@ -31,7 +31,7 @@ The following packages will be upgraded:
After this operation, 0 B of additional disk space will be used.
E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only
-aptmark hold apt -qq
+testsuccess aptmark hold apt
testequal 'Reading package lists...
Building dependency tree...
diff --git a/test/integration/test-bug-673536-pre-depends-breaks-loop b/test/integration/test-bug-673536-pre-depends-breaks-loop
index e9d3c4de6..f6a90b21f 100755
--- a/test/integration/test-bug-673536-pre-depends-breaks-loop
+++ b/test/integration/test-bug-673536-pre-depends-breaks-loop
@@ -15,9 +15,9 @@ setupaptarchive
# we check with 'real' packages here as the simulation reports a 'Conf broken'
# which is technical correct for the simulation, but testing errormsg is ugly
-aptget install basic=1 -qq > /dev/null
+testsuccess aptget install basic=1 -y
testdpkginstalled basic
testdpkgnotinstalled common
-aptget dist-upgrade -qq > /dev/null
+testsuccess aptget dist-upgrade -y
testdpkginstalled basic common
diff --git a/test/integration/test-bug-679371-apt-get-autoclean-multiarch b/test/integration/test-bug-679371-apt-get-autoclean-multiarch
index ba6857b73..b62d437aa 100755
--- a/test/integration/test-bug-679371-apt-get-autoclean-multiarch
+++ b/test/integration/test-bug-679371-apt-get-autoclean-multiarch
@@ -14,8 +14,8 @@ setupaptarchive
changetowebserver
-aptget update -qq
-aptget install pkgall pkgnative pkgforeign -y -qq > /dev/null
+testsuccess aptget update
+testsuccess aptget install pkgall pkgnative pkgforeign -y
testdpkginstalled pkgall pkgnative pkgforeign
diff --git a/test/integration/test-bug-686346-package-missing-architecture b/test/integration/test-bug-686346-package-missing-architecture
index b2c9ec9ee..3b02811ca 100755
--- a/test/integration/test-bug-686346-package-missing-architecture
+++ b/test/integration/test-bug-686346-package-missing-architecture
@@ -58,13 +58,13 @@ Building dependency tree...
# pkgd has no update with an architecture
testdpkginstalled pkgd
msgtest 'Test apt-get purge' 'pkgd'
-aptget purge pkgd -y >/dev/null 2>&1 && msgpass || msgfail
+testsuccess --nomsg aptget purge pkgd -y
testdpkgnotinstalled pkgd
# there is a pkgb with an architecture
testdpkginstalled pkgb
msgtest 'Test apt-get purge' 'pkgb:none'
-aptget purge pkgb:none -y >/dev/null 2>&1 && msgpass || msgfail
+testsuccess --nomsg aptget purge pkgb:none -y
testdpkgnotinstalled pkgb
# check that dependencies are created after the none package exists in the cache
diff --git a/test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch b/test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch
index a89cb7191..62355a6b5 100755
--- a/test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch
+++ b/test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch
@@ -26,95 +26,111 @@ hook='pre-install-pkgs'
enablehookversion() {
echo "#!/bin/sh
-while read line; do
+FD=0
+echo -n > ${hook}-v${1}.list
+if [ -n \"${2}\" ]; then
+ FD=\$APT_HOOK_INFO_FD
+ if [ "\$FD" != \"${2}\" ]; then echo \"ERROR: Information is not on requested FD: \$FD != ${2}\" >> ${hook}-v${1}.list; fi
+fi
+while read </proc/\$\$/fd/\$FD line; do
if echo \"\$line\" | grep -Fq '**'; then
echo \"\$line\"
fi
-done > ${hook}-v${1}.list" > ${hook}-v${1}.sh
+done >> ${hook}-v${1}.list" > ${hook}-v${1}.sh
chmod +x ${hook}-v${1}.sh
echo "dpkg::${hook}:: \"./${hook}-v${1}.sh --foo -bar\";
DPkg::Tools::options::\"./${hook}-v${1}.sh\"::Version \"$1\";" > rootdir/etc/apt/apt.conf.d/hook-v$1
+ if [ -n "$2" ]; then
+ echo "DPkg::Tools::options::\"./${hook}-v${1}.sh\"::InfoFD \"${2}\";" >> rootdir/etc/apt/apt.conf.d/hook-v$1
+ fi
}
-enablehookversion 2
-enablehookversion 3
-
observehook() {
rm -f ${hook}-v2.list ${hook}-v3.list
msgtest 'Observe hooks while' "$*"
- aptget "$@" -y --force-yes >/dev/null 2>&1 && msgpass || msgfail
+ testsuccess --nomsg aptget "$@" -y --force-yes
}
-observehook install stuff -t stable
-testfileequal "${hook}-v2.list" 'libsame - < 1 **CONFIGURE**
+testrun() {
+ observehook install stuff -t stable
+ testfileequal "${hook}-v2.list" 'libsame - < 1 **CONFIGURE**
toolkit - < 1 **CONFIGURE**
stuff - < 1 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'libsame - - none < 1 amd64 same **CONFIGURE**
+ testfileequal "${hook}-v3.list" 'libsame - - none < 1 amd64 same **CONFIGURE**
toolkit - - none < 1 all foreign **CONFIGURE**
stuff - - none < 1 amd64 none **CONFIGURE**'
-observehook install stuff -t unstable
-testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
+ observehook install stuff -t unstable
+ testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
toolkit 1 < 2 **CONFIGURE**
stuff 1 < 2 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'libsame 1 amd64 same < 2 amd64 same **CONFIGURE**
+ testfileequal "${hook}-v3.list" 'libsame 1 amd64 same < 2 amd64 same **CONFIGURE**
toolkit 1 all foreign < 2 amd64 foreign **CONFIGURE**
stuff 1 amd64 none < 2 amd64 none **CONFIGURE**'
-observehook install stuff:i386 -t unstable
-testfileequal "${hook}-v2.list" 'stuff 2 > - **REMOVE**
+ observehook install stuff:i386 -t unstable
+ testfileequal "${hook}-v2.list" 'stuff 2 > - **REMOVE**
libsame - < 2 **CONFIGURE**
stuff - < 2 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'stuff 2 amd64 none > - - none **REMOVE**
+ testfileequal "${hook}-v3.list" 'stuff 2 amd64 none > - - none **REMOVE**
libsame - - none < 2 i386 same **CONFIGURE**
stuff - - none < 2 i386 none **CONFIGURE**'
-observehook remove libsame
-testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**'
-testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**'
+ observehook remove libsame
+ testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**'
+ testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**'
-observehook install stuff:i386/stable libsame:i386/stable toolkit/stable
-testfileequal "${hook}-v2.list" 'libsame 2 > 1 **CONFIGURE**
+ observehook install stuff:i386/stable libsame:i386/stable toolkit/stable
+ testfileequal "${hook}-v2.list" 'libsame 2 > 1 **CONFIGURE**
toolkit 2 > 1 **CONFIGURE**
stuff 2 > 1 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'libsame 2 i386 same > 1 i386 same **CONFIGURE**
+ testfileequal "${hook}-v3.list" 'libsame 2 i386 same > 1 i386 same **CONFIGURE**
toolkit 2 amd64 foreign > 1 all foreign **CONFIGURE**
stuff 2 i386 none > 1 i386 none **CONFIGURE**'
-observehook install 'libsame:*'
-testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
+ observehook install 'libsame:*'
+ testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
libsame - < 2 **CONFIGURE**
toolkit 1 < 2 **CONFIGURE**
stuff 1 < 2 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'libsame 1 i386 same < 2 i386 same **CONFIGURE**
+ testfileequal "${hook}-v3.list" 'libsame 1 i386 same < 2 i386 same **CONFIGURE**
libsame - - none < 2 amd64 same **CONFIGURE**
toolkit 1 all foreign < 2 amd64 foreign **CONFIGURE**
stuff 1 i386 none < 2 i386 none **CONFIGURE**'
-observehook purge stuff:i386 'libsame:*' toolkit
-testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**
+ observehook purge stuff:i386 'libsame:*' toolkit
+ testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**
stuff 2 > - **REMOVE**
libsame 2 > - **REMOVE**
toolkit 2 > - **REMOVE**'
-testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**
+ testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**
stuff 2 i386 none > - - none **REMOVE**
libsame 2 i386 same > - - none **REMOVE**
toolkit 2 amd64 foreign > - - none **REMOVE**'
-observehook install confpkg
-testfileequal "${hook}-v2.list" 'confpkg - < 1 **CONFIGURE**'
-testfileequal "${hook}-v3.list" 'confpkg - - none < 1 amd64 none **CONFIGURE**'
+ observehook install confpkg
+ testfileequal "${hook}-v2.list" 'confpkg - < 1 **CONFIGURE**'
+ testfileequal "${hook}-v3.list" 'confpkg - - none < 1 amd64 none **CONFIGURE**'
+
+ observehook remove confpkg
+ testfileequal "${hook}-v2.list" 'confpkg 1 > - **REMOVE**'
+ testfileequal "${hook}-v3.list" 'confpkg 1 amd64 none > - - none **REMOVE**'
-observehook remove confpkg
-testfileequal "${hook}-v2.list" 'confpkg 1 > - **REMOVE**'
-testfileequal "${hook}-v3.list" 'confpkg 1 amd64 none > - - none **REMOVE**'
+ msgtest 'Conffiles of package remained after remove' 'confpkg'
+ dpkg -l confpkg | grep -q '^rc' && msgpass || msgfail
-msgtest 'Conffiles of package remained after remove' 'confpkg'
-dpkg -l confpkg | grep -q '^rc' && msgpass || msgfail
+ observehook purge confpkg
+ testfileequal "${hook}-v2.list" 'confpkg 1 > - **REMOVE**'
+ testfileequal "${hook}-v3.list" 'confpkg 1 amd64 none > - - none **REMOVE**'
-observehook purge confpkg
-testfileequal "${hook}-v2.list" 'confpkg 1 > - **REMOVE**'
-testfileequal "${hook}-v3.list" 'confpkg 1 amd64 none > - - none **REMOVE**'
+ msgtest 'Conffiles are gone after purge' 'confpkg'
+ dpkg -l confpkg 2>/dev/null | grep -q '^rc' && msgfail || msgpass
+}
+
+enablehookversion 2
+enablehookversion 3
+testrun
-msgtest 'Conffiles are gone after purge' 'confpkg'
-dpkg -l confpkg 2>/dev/null | grep -q '^rc' && msgfail || msgpass
+enablehookversion 2 13
+enablehookversion 3 13
+testrun
diff --git a/test/integration/test-bug-717891-abolute-uris-for-proxies b/test/integration/test-bug-717891-abolute-uris-for-proxies
index e9c38492e..ac1d6ec11 100755
--- a/test/integration/test-bug-717891-abolute-uris-for-proxies
+++ b/test/integration/test-bug-717891-abolute-uris-for-proxies
@@ -12,12 +12,12 @@ setupaptarchive
changetowebserver --request-absolute='uri'
msgtest 'Check that absolute paths are' 'not accepted'
-aptget update >/dev/null 2>&1 && msgfail || msgpass
+testfailure --nomsg aptget update
echo 'Acquire::http::Proxy "http://localhost:8080";' > rootdir/etc/apt/apt.conf.d/99proxy
msgtest 'Check that requests to proxies are' 'absolute uris'
-aptget update >/dev/null 2>&1 && msgpass || msgfail
+testsuccess --nomsg aptget update
testequal 'Reading package lists...
Building dependency tree...
diff --git a/test/integration/test-bug-719263-print-uris-removes-authentication b/test/integration/test-bug-719263-print-uris-removes-authentication
new file mode 100755
index 000000000..1c1a27ceb
--- /dev/null
+++ b/test/integration/test-bug-719263-print-uris-removes-authentication
@@ -0,0 +1,41 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture 'amd64'
+
+insertinstalledpackage 'unrelated' 'all' '1'
+buildsimplenativepackage 'unrelated' 'all' '2' 'unstable'
+
+setupaptarchive
+
+testnoact() {
+ cp -a rootdir/var/lib/dpkg/status rootdir/var/lib/dpkg/status-backup-noact
+ touch rootdir/var/lib/apt/extended_states
+ testequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be upgraded:
+ unrelated
+1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
+Inst unrelated [1] (2 unstable [all])
+Conf unrelated (2 unstable [all])' aptget install unrelated -s
+ testsuccess aptget install unrelated -y
+ testdpkginstalled unrelated
+ cp -a rootdir/var/lib/dpkg/status-backup-noact rootdir/var/lib/dpkg/status
+}
+
+testnoact
+testsuccess aptget update --print-uris
+testnoact
+
+# same thing, just not with InRelease this time
+rm -rf rootdir/var/lib/apt/lists
+testsuccess aptget update -o Acquire::TryInRelease=0
+
+testnoact
+testsuccess aptget update --print-uris -o Acquire::TryInRelease=0
+testnoact
diff --git a/test/integration/test-compressed-indexes b/test/integration/test-compressed-indexes
index a5e885745..c6f5ab49e 100755
--- a/test/integration/test-compressed-indexes
+++ b/test/integration/test-compressed-indexes
@@ -46,10 +46,10 @@ testrun() {
msgpass
fi
msgtest "Check if package is downloadable"
- aptget install -d testpkg -qq && msgpass || msgfail
- msgtest "\tdeb file is present"; test -f rootdir/var/cache/apt/archives/testpkg_1.0_i386.deb && msgpass || msgfail
+ testsuccess --nomsg aptget install -d testpkg
+ msgtest "\tdeb file is present"; testsuccess --nomsg test -f rootdir/var/cache/apt/archives/testpkg_1.0_i386.deb
aptget clean
- msgtest "\tdeb file is gone"; ! test -f rootdir/var/cache/apt/archives/testpkg_1.0_i386.deb && msgpass || msgfail
+ msgtest "\tdeb file is gone"; testfailure --nomsg test -f rootdir/var/cache/apt/archives/testpkg_1.0_i386.deb
fi
rm -f rootdir/var/cache/apt/pkgcache.bin rootdir/var/cache/apt/srcpkgcache.bin
testequal "$GOODSHOW" aptcache show testpkg
@@ -62,9 +62,9 @@ testrun() {
testequal "$GOODSHOWSRC" aptcache showsrc testpkg
aptget clean
msgtest "Check if the source is aptgetable"
- aptget source testpkg -qq 2> /dev/null > /dev/null && msgpass || msgfail
- msgtest "\tdsc file is present"; test -f testpkg_1.0.dsc && msgpass || msgfail
- msgtest "\tdirectory is present"; test -d testpkg-1.0 && msgpass || msgfail
+ testsuccess --nomsg aptget source testpkg
+ msgtest "\tdsc file is present"; testsuccess --nomsg test -f testpkg_1.0.dsc
+ msgtest "\tdirectory is present"; testsuccess --nomsg test -d testpkg-1.0
rm -rf testpkg-1.0
}
@@ -72,11 +72,11 @@ echo 'Acquire::GzipIndexes "false";' > rootdir/etc/apt/apt.conf.d/02compressinde
msgmsg "File: Test with uncompressed indexes"
testrun
-aptget update -qq -o Acquire::Pdiffs=1
+testsuccess aptget update -o Acquire::Pdiffs=1
msgmsg "File: Test with uncompressed indexes (update unchanged with pdiffs)"
testrun
-aptget update -qq -o Acquire::Pdiffs=0
+testsuccess aptget update -o Acquire::Pdiffs=0
msgmsg "File: Test with uncompressed indexes (update unchanged without pdiffs)"
testrun
@@ -84,21 +84,21 @@ rm -rf rootdir/var/lib/apt/lists
echo 'Acquire::CompressionTypes::Order:: "gz";
Acquire::GzipIndexes "true";' > rootdir/etc/apt/apt.conf.d/02compressindex
-aptget update -qq
+testsuccess aptget update
msgmsg "File: Test with compressed indexes"
testrun "compressed"
-aptget update -qq -o Acquire::Pdiffs=1
+testsuccess aptget update -o Acquire::Pdiffs=1
msgmsg "File: Test with compressed indexes (update unchanged with pdiffs)"
testrun "compressed"
-aptget update -qq -o Acquire::Pdiffs=0
+testsuccess aptget update -o Acquire::Pdiffs=0
msgmsg "File: Test with compressed indexes (update unchanged without pdiffs)"
testrun "compressed"
rm rootdir/etc/apt/apt.conf.d/02compressindex
changetowebserver
-aptget update -qq
+testsuccess aptget update
GOODPOLICY="$(aptcache policy testpkg)"
test $(echo "$GOODPOLICY" | grep -e '^testpkg:' -e '^ Candidate:' -e '^ Installed: (none)' -e '500 http://' | wc -l) -eq 4
testequal "$GOODPOLICY" aptcache policy testpkg
@@ -106,11 +106,11 @@ testequal "$GOODPOLICY" aptcache policy testpkg
msgmsg "HTTP: Test with uncompressed indexes"
testrun
-aptget update -qq -o Acquire::Pdiffs=1
+testsuccess aptget update -o Acquire::Pdiffs=1
msgmsg "HTTP: Test with uncompressed indexes (update unchanged with pdiffs)"
testrun
-aptget update -qq -o Acquire::Pdiffs=0
+testsuccess aptget update -o Acquire::Pdiffs=0
msgmsg "HTTP: Test with uncompressed indexes (update unchanged without pdiffs)"
testrun
@@ -118,14 +118,14 @@ rm -rf rootdir/var/lib/apt/lists
echo 'Acquire::CompressionTypes::Order:: "gz";
Acquire::GzipIndexes "true";' > rootdir/etc/apt/apt.conf.d/02compressindex
-aptget update -qq
+testsuccess aptget update
msgmsg "HTTP: Test with compressed indexes"
testrun "compressed"
-aptget update -qq -o Acquire::Pdiffs=1
+testsuccess aptget update -o Acquire::Pdiffs=1
msgmsg "HTTP: Test with compressed indexes (update unchanged with pdiffs)"
testrun "compressed"
-aptget update -qq -o Acquire::Pdiffs=0
+testsuccess aptget update -o Acquire::Pdiffs=0
msgmsg "HTTP: Test with compressed indexes (update unchanged without pdiffs)"
testrun "compressed"
diff --git a/test/integration/test-cve-2013-1051-InRelease-parsing b/test/integration/test-cve-2013-1051-InRelease-parsing
index 6764fefff..41b27f691 100755
--- a/test/integration/test-cve-2013-1051-InRelease-parsing
+++ b/test/integration/test-cve-2013-1051-InRelease-parsing
@@ -14,7 +14,7 @@ setupaptarchive
changetowebserver
ARCHIVE='http://localhost:8080/'
msgtest 'Initial apt-get update should work with' 'InRelease'
-aptget update -qq && msgpass || msgfail
+testsuccess --nomsg aptget update
# check that the setup is correct
testequal "good-pkg:
diff --git a/test/integration/test-disappearing-packages b/test/integration/test-disappearing-packages
index d2ac4edc6..09dbf7014 100755
--- a/test/integration/test-disappearing-packages
+++ b/test/integration/test-disappearing-packages
@@ -29,7 +29,7 @@ rm -rf "$BUILDDIR"
setupaptarchive
-aptget install old-pkg=1.0 --trivial-only -qq 2>&1 > /dev/null
+testsuccess aptget install old-pkg=1.0 --trivial-only
testmarkedauto # old-pkg is manual installed
diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage
index e45326970..994489ee5 100755
--- a/test/integration/test-pdiff-usage
+++ b/test/integration/test-pdiff-usage
@@ -11,7 +11,7 @@ buildaptarchive
setupflataptarchive
changetowebserver
signreleasefiles
-aptget update -qq
+testsuccess aptget update
testnopackage newstuff
PKGFILE="${TESTDIR}/$(echo "$(basename $0)" | sed 's#^test-#Packages-#')"
@@ -38,7 +38,7 @@ SHA1-Patches:
generatereleasefiles '+1hour'
signreleasefiles
find aptarchive -name 'Packages*' -type f -delete
-aptget update -qq
+testsuccess aptget update
testnopackage oldstuff
testequal "$(cat ${PKGFILE}-new)
diff --git a/test/integration/test-policy-pinning b/test/integration/test-policy-pinning
index 9e1ea4ac5..8eb4bcbad 100755
--- a/test/integration/test-policy-pinning
+++ b/test/integration/test-policy-pinning
@@ -228,16 +228,16 @@ testequalpolicycoolstuff "" "2.0~bpo1" 990 500 600 "2.0~bpo1" -o Test=ButAutomat
testequalpolicycoolstuff "" "1.0" 100 990 600 "2.0~bpo1" -o Test=ButAutomaticUpgrades -t stable
rm rootdir/etc/apt/preferences
-aptget install coolstuff -qq > /dev/null 2> /dev/null
+testsuccess aptget install coolstuff -y
testequalpolicycoolstuff "1.0" "1.0" 100 500 0 "" -o Test=ButAutomaticUpgrades
-aptget dist-upgrade -qq > /dev/null 2> /dev/null
+testsuccess aptget dist-upgrade -y
testequalpolicycoolstuff "1.0" "1.0" 100 500 0 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "1.0" "1.0" 100 990 0 "" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "1.0" "2.0~bpo1" 990 500 0 "" -o Test=ButAutomaticUpgrades -t backports
-aptget install coolstuff -t backports -qq > /dev/null 2> /dev/null
+testsuccess aptget install coolstuff -t backports -y
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 500 0 "" -o Test=ButAutomaticUpgrades
-aptget dist-upgrade -qq > /dev/null 2> /dev/null
+testsuccess aptget dist-upgrade -y
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 500 0 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 990 0 "" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 990 500 0 "" -o Test=ButAutomaticUpgrades -t backports
diff --git a/test/integration/test-releasefile-valid-until b/test/integration/test-releasefile-valid-until
index 680a370cb..e673d5f71 100755
--- a/test/integration/test-releasefile-valid-until
+++ b/test/integration/test-releasefile-valid-until
@@ -32,64 +32,64 @@ aptgetupdate() {
setupreleasefile
msgtest 'Release file is accepted as it has' 'no Until'
-aptgetupdate && msgpass || msgfail
+testsuccess --nomsg aptgetupdate
setupreleasefile
msgtest 'Release file is accepted as it has' 'no Until and good Max-Valid'
-aptgetupdate -o Acquire::Max-ValidTime=3600 && msgpass || msgfail
+testsuccess --nomsg aptgetupdate -o Acquire::Max-ValidTime=3600
setupreleasefile 'now - 2 days'
msgtest 'Release file is rejected as it has' 'no Until, but bad Max-Valid'
-aptgetupdate -o Acquire::Max-ValidTime=3600 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=3600
setupreleasefile 'now - 3 days' 'now + 1 day'
msgtest 'Release file is accepted as it has' 'good Until'
-aptgetupdate && msgpass || msgfail
+testsuccess --nomsg aptgetupdate
setupreleasefile 'now - 7 days' 'now - 4 days'
msgtest 'Release file is rejected as it has' 'bad Until'
-aptgetupdate && msgfail || msgpass
+testfailure --nomsg aptgetupdate
setupreleasefile 'now - 7 days' 'now - 4 days'
msgtest 'Release file is rejected as it has' 'bad Until (ignore good Max-Valid)'
-aptgetupdate -o Acquire::Max-ValidTime=1209600 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=1209600
setupreleasefile 'now - 7 days' 'now - 4 days'
msgtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until)'
-aptgetupdate -o Acquire::Max-ValidTime=86400 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=86400
setupreleasefile 'now - 7 days' 'now + 4 days'
msgtest 'Release file is rejected as it has' 'bad Max-Valid (good Until)'
-aptgetupdate -o Acquire::Max-ValidTime=86400 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=86400
setupreleasefile 'now - 7 days' 'now + 4 days'
msgtest 'Release file is accepted as it has' 'good labeled Max-Valid'
-aptgetupdate -o Acquire::Max-ValidTime=86400 -o Acquire::Max-ValidTime::Testcases=1209600 && msgpass || msgfail
+testsuccess --nomsg aptgetupdate -o Acquire::Max-ValidTime=86400 -o Acquire::Max-ValidTime::Testcases=1209600
setupreleasefile 'now - 7 days' 'now + 4 days'
msgtest 'Release file is rejected as it has' 'bad labeled Max-Valid'
-aptgetupdate -o Acquire::Max-ValidTime=1209600 -o Acquire::Max-ValidTime::Testcases=86400 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=1209600 -o Acquire::Max-ValidTime::Testcases=86400
setupreleasefile 'now - 7 days' 'now + 1 days'
msgtest 'Release file is accepted as it has' 'good Until (good Min-Valid, no Max-Valid)'
-aptgetupdate -o Acquire::Min-ValidTime=1209600 && msgpass || msgfail
+testsuccess --nomsg aptgetupdate -o Acquire::Min-ValidTime=1209600
setupreleasefile 'now - 7 days' 'now - 4 days'
msgtest 'Release file is accepted as it has' 'good Min-Valid (bad Until, no Max-Valid)'
-aptgetupdate -o Acquire::Min-ValidTime=1209600 && msgpass || msgfail
+testsuccess --nomsg aptgetupdate -o Acquire::Min-ValidTime=1209600
setupreleasefile 'now - 7 days' 'now - 2 days'
msgtest 'Release file is accepted as it has' 'good Min-Valid (bad Until, good Max-Valid) <'
-aptgetupdate -o Acquire::Min-ValidTime=1209600 -o Acquire::Max-ValidTime=2419200 && msgpass || msgfail
+testsuccess --nomsg aptgetupdate -o Acquire::Min-ValidTime=1209600 -o Acquire::Max-ValidTime=2419200
setupreleasefile 'now - 7 days' 'now - 2 days'
msgtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, good Min-Valid) >'
-aptgetupdate -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=2419200 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=2419200
setupreleasefile 'now - 7 days' 'now - 2 days'
msgtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, bad Min-Valid) <'
-aptgetupdate -o Acquire::Min-ValidTime=12096 -o Acquire::Max-ValidTime=241920 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Min-ValidTime=12096 -o Acquire::Max-ValidTime=241920
setupreleasefile 'now - 7 days' 'now - 2 days'
msgtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, bad Min-Valid) >'
-aptgetupdate -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=241920 && msgfail || msgpass
+testfailure --nomsg aptgetupdate -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=241920
diff --git a/test/integration/test-releasefile-verification b/test/integration/test-releasefile-verification
index e56f458d3..daba3919b 100755
--- a/test/integration/test-releasefile-verification
+++ b/test/integration/test-releasefile-verification
@@ -107,13 +107,24 @@ runtest() {
" aptcache show apt
installaptnew
+ prepare ${PKGFILE}
+ rm -rf rootdir/var/lib/apt/lists
+ cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
+ signreleasefiles 'Rex Expired'
+ find aptarchive/ -name "$DELETEFILE" -delete
+ msgtest 'Cold archive signed by' 'Rex Expired'
+ aptget update 2>&1 | grep -E '^W: .* KEYEXPIRED' > /dev/null && msgpass || msgfail
+ testequal "$(cat ${PKGFILE})
+" aptcache show apt
+ failaptold
+ rm rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
prepare ${PKGFILE}
rm -rf rootdir/var/lib/apt/lists
signreleasefiles 'Marvin Paranoid'
find aptarchive/ -name "$DELETEFILE" -delete
msgtest 'Cold archive signed by' 'Marvin Paranoid'
- aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgpass || msgfail
+ aptget update 2>&1 | grep -E '^W: .* NO_PUBKEY' > /dev/null && msgpass || msgfail
testequal "$(cat ${PKGFILE})
" aptcache show apt
failaptold
@@ -147,10 +158,30 @@ runtest() {
signreleasefiles 'Marvin Paranoid'
find aptarchive/ -name "$DELETEFILE" -delete
msgtest 'Good warm archive signed by' 'Marvin Paranoid'
- aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgpass || msgfail
+ aptget update 2>&1 | grep -E '^W: .* NO_PUBKEY' > /dev/null && msgpass || msgfail
+ testequal "$(cat ${PKGFILE})
+" aptcache show apt
+ installaptold
+
+ prepare ${PKGFILE}-new
+ cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
+ signreleasefiles 'Rex Expired'
+ find aptarchive/ -name "$DELETEFILE" -delete
+ msgtest 'Good warm archive signed by' 'Rex Expired'
+ aptget update 2>&1 | grep -E '^W: .* KEYEXPIRED' > /dev/null && msgpass || msgfail
testequal "$(cat ${PKGFILE})
" aptcache show apt
installaptold
+ rm rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
+
+ prepare ${PKGFILE}-new
+ signreleasefiles
+ find aptarchive/ -name "$DELETEFILE" -delete
+ msgtest 'Good warm archive signed by' 'Joe Sixpack'
+ aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass
+ testequal "$(cat ${PKGFILE}-new)
+" aptcache show apt
+ installaptnew
}
runtest2() {
diff --git a/test/integration/test-ubuntu-bug-761175-remove-purge b/test/integration/test-ubuntu-bug-761175-remove-purge
index f55c6e909..14648e9b8 100755
--- a/test/integration/test-ubuntu-bug-761175-remove-purge
+++ b/test/integration/test-ubuntu-bug-761175-remove-purge
@@ -18,12 +18,10 @@ setupaptarchive
testdpkgnotinstalled compiz-core
-msgtest 'Install package' 'compiz-core'
-aptget install compiz-core -qq 2>&1 >/dev/null && msgpass || msgfail
+testsuccess aptget install compiz-core
testdpkginstalled compiz-core
-msgtest 'Remove package' 'compiz-core'
-aptget remove compiz-core -y -qq 2>&1 >/dev/null && msgpass || msgfail
+testsuccess aptget remove compiz-core -y
testdpkgnotinstalled compiz-core
msgtest 'Check that conffiles are still around for' 'compiz-core'
diff --git a/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only
index fad5488fb..e9d684309 100755
--- a/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only
+++ b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only
@@ -28,7 +28,7 @@ MD5Sum:
done
msgtest 'The unsigned garbage before signed block is' 'ignored'
-aptget update -qq > /dev/null 2>&1 && msgpass || msgfail
+testsuccess --nomsg aptget update
ROOTDIR="$(readlink -f .)"
testequal "Package files:
diff --git a/test/libapt/configuration_test.cc b/test/libapt/configuration_test.cc
index 87d5699ef..2c974ee0a 100644
--- a/test/libapt/configuration_test.cc
+++ b/test/libapt/configuration_test.cc
@@ -98,6 +98,10 @@ int main(int argc,const char *argv[]) {
equals(Cnf.FindDir("Dir::State"), "/rootdir/dev/null");
equals(Cnf.FindDir("Dir::State::lists"), "/rootdir/dev/null");
+ Cnf.Set("Moo::Bar", "1");
+ Cnf.Clear();
+ equals(Cnf.Find("Moo::Bar"), "");
+
//FIXME: Test for configuration file parsing;
// currently only integration/ tests test them implicitly
diff --git a/test/libapt/fileutl_test.cc b/test/libapt/fileutl_test.cc
new file mode 100644
index 000000000..b6b8ac579
--- /dev/null
+++ b/test/libapt/fileutl_test.cc
@@ -0,0 +1,42 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+
+#include "assert.h"
+#include <string>
+#include <vector>
+
+#include <stdio.h>
+#include <iostream>
+#include <stdlib.h>
+
+
+int main(int argc,char *argv[])
+{
+ std::vector<std::string> files;
+
+ // normal match
+ files = Glob("*.lst");
+ if (files.size() != 1)
+ {
+ _error->DumpErrors();
+ return 1;
+ }
+
+ // not there
+ files = Glob("xxxyyyzzz");
+ if (files.size() != 0 || _error->PendingError())
+ {
+ _error->DumpErrors();
+ return 1;
+ }
+
+ // many matches (number is a bit random)
+ files = Glob("*.cc");
+ if (files.size() < 10)
+ {
+ _error->DumpErrors();
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/libapt/makefile b/test/libapt/makefile
index 1b67cba9d..73403b24c 100644
--- a/test/libapt/makefile
+++ b/test/libapt/makefile
@@ -98,6 +98,11 @@ include $(PROGRAM_H)
PROGRAM = IndexCopyToSourceList${BASENAME}
SLIBS = -lapt-pkg
SOURCE = indexcopytosourcelist_test.cc
+
+# test fileutls
+PROGRAM = FileUtl${BASENAME}
+SLIBS = -lapt-pkg
+SOURCE = fileutl_test.cc
include $(PROGRAM_H)
# test tagfile
diff --git a/test/libapt/run-tests b/test/libapt/run-tests
index f18be6d2b..a056f31f9 100755
--- a/test/libapt/run-tests
+++ b/test/libapt/run-tests
@@ -2,9 +2,11 @@
set -e
DIR=$(readlink -f $(dirname $0))
-echo "Compiling the tests …"
-(cd $DIR && make)
-echo "Running all testcases …"
+if [ -z "$MAKELEVEL" ]; then
+ echo 'Compiling the tests …'
+ (cd $DIR && make)
+ echo 'Running all testcases …'
+fi
LDPATH="$DIR/../../build/bin"
EXT="_libapt_test"
EXIT_CODE=0
@@ -70,9 +72,11 @@ do
"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-tlh%5fDE"
elif [ $name = "HashSums${EXT}" ]; then
TMP="$(readlink -f "./${0}")"
- echo -n "Testing with ${NAME} "
- LD_LIBRARY_PATH=${LDPATH} ${testapp} $TMP $(md5sum $TMP | cut -d' ' -f 1) $(sha1sum $TMP | cut -d' ' -f 1) $(sha256sum $TMP | cut -d' ' -f 1) $(sha512sum $TMP | cut -d' ' -f 1) && echo "$TESTOKAY" || echo "$TESTFAIL"
- continue
+ tmppath="$TMP"
+ tmppath="${tmppath} $(md5sum $TMP | cut -d' ' -f 1)"
+ tmppath="${tmppath} $(sha1sum $TMP | cut -d' ' -f 1)"
+ tmppath="${tmppath} $(sha256sum $TMP | cut -d' ' -f 1)"
+ tmppath="${tmppath} $(sha512sum $TMP | cut -d' ' -f 1)"
elif [ $name = "CompareVersion${EXT}" ]; then
tmppath="${DIR}/versions.lst"
elif [ $name = "CdromFindPackages${EXT}" ]; then
@@ -107,8 +111,8 @@ do
fi
echo -n "Testing with ${NAME} "
- if LD_LIBRARY_PATH=${LDPATH} ${testapp} ${tmppath} ; then
- echo "$TESTOKAY"
+ if MALLOC_PERTURB_=21 MALLOC_CHECK_=2 LD_LIBRARY_PATH=${LDPATH} ${testapp} ${tmppath} ; then
+ echo "$TESTOKAY"
else
echo "$TESTFAIL"
EXIT_CODE=1