Browse Source

fix support for multiple patterns in apt-cache search

Patterns can appear in the name as well as in the description,
they don't have to match all in the name/description only.

Closes: 691453
tags/debian/0.9.9
David Kalnischkies 8 years ago
parent
commit
8ba17539a3
4 changed files with 94 additions and 36 deletions
  1. +51
    -28
      cmdline/apt-cache.cc
  2. +1
    -5
      debian/changelog
  3. +9
    -3
      test/integration/framework
  4. +33
    -0
      test/integration/test-bug-691453-apt-cache-search-multi-pattern

+ 51
- 28
cmdline/apt-cache.cc View File

@@ -1203,7 +1203,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
struct ExDescFile
{
pkgCache::DescFile *Df;
bool NameMatch;
map_ptrloc ID;
};

// Search - Perform a search /*{{{*/
@@ -1246,37 +1246,48 @@ bool Search(CommandLine &CmdL)
return false;
}
ExDescFile *DFList = new ExDescFile[Cache->HeaderP->GroupCount+1];
memset(DFList, 0, sizeof(*DFList) * (Cache->HeaderP->GroupCount + 1));
size_t const descCount = Cache->HeaderP->GroupCount + 1;
ExDescFile *DFList = new ExDescFile[descCount];
memset(DFList,0,sizeof(*DFList) * descCount);

bool PatternMatch[descCount * NumPatterns];
memset(PatternMatch,false,sizeof(PatternMatch));

// Map versions that we want to write out onto the VerList array.
for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
{
if (DFList[G->ID].NameMatch == true)
continue;

DFList[G->ID].NameMatch = true;
for (unsigned I = 0; I != NumPatterns; I++)
size_t const PatternOffset = G->ID * NumPatterns;
size_t unmatched = 0, matched = 0;
for (unsigned I = 0; I < NumPatterns; ++I)
{
if (regexec(&Patterns[I],G.Name(),0,0,0) == 0)
continue;
DFList[G->ID].NameMatch = false;
break;
if (PatternMatch[PatternOffset + I] == true)
++matched;
else if (regexec(&Patterns[I],G.Name(),0,0,0) == 0)
PatternMatch[PatternOffset + I] = true;
else
++unmatched;
}
// Doing names only, drop any that dont match..
if (NamesOnly == true && DFList[G->ID].NameMatch == false)
// already dealt with this package?
if (matched == NumPatterns)
continue;

// Doing names only, drop any that don't match..
if (NamesOnly == true && unmatched == NumPatterns)
continue;

// Find the proper version to use
pkgCache::PkgIterator P = G.FindPreferredPkg();
if (P.end() == true)
continue;
pkgCache::VerIterator V = Plcy->GetCandidateVer(P);
if (V.end() == false)
{
DFList[G->ID].Df = V.TranslatedDescription().FileList();
DFList[G->ID].ID = G->ID;
}

if (DFList[G->ID].NameMatch == false)
if (unmatched == NumPatterns)
continue;

// Include all the packages that provide matching names too
@@ -1288,33 +1299,45 @@ bool Search(CommandLine &CmdL)

unsigned long id = Prv.OwnerPkg().Group()->ID;
DFList[id].Df = V.TranslatedDescription().FileList();
DFList[id].NameMatch = true;
DFList[id].ID = id;

size_t const PrvPatternOffset = id * NumPatterns;
for (unsigned I = 0; I < NumPatterns; ++I)
PatternMatch[PrvPatternOffset + I] = PatternMatch[PatternOffset + I];
}
}
LocalitySort(&DFList->Df,Cache->HeaderP->GroupCount,sizeof(*DFList));

// Create the text record parser
pkgRecords Recs(*Cache);
// Iterate over all the version records and check them
for (ExDescFile *J = DFList; J->Df != 0; J++)
for (ExDescFile *J = DFList; J->Df != 0; ++J)
{
pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(*Cache,J->Df));
size_t const PatternOffset = J->ID * NumPatterns;

if (J->NameMatch == false && NamesOnly == false)
if (NamesOnly == false)
{
string const LongDesc = P.LongDesc();
J->NameMatch = true;
for (unsigned I = 0; I != NumPatterns; I++)
for (unsigned I = 0; I < NumPatterns; ++I)
{
if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0)
if (PatternMatch[PatternOffset + I] == true)
continue;
J->NameMatch = false;
break;
else if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0)
PatternMatch[PatternOffset + I] = true;
}
}
if (J->NameMatch == true)

bool matchedAll = true;
for (unsigned I = 0; I < NumPatterns; ++I)
if (PatternMatch[PatternOffset + I] == false)
{
matchedAll = false;
break;
}

if (matchedAll == true)
{
if (ShowFull == true)
{


+ 1
- 5
debian/changelog View File

@@ -9,6 +9,7 @@ apt (0.9.8.3) UNRELEASED; urgency=low
* fix priority sorting by prefering higher in MarkInstall
* try all providers in order if uninstallable in MarkInstall
* do unpacks before configures in SmartConfigure (Closes: #707578)
* fix support for multiple patterns in apt-cache search (Closes: #691453)

-- David Kalnischkies <kalnischkies@gmail.com> Sun, 09 Jun 2013 15:06:24 +0200

@@ -31,11 +32,6 @@ apt (0.9.8.2) unstable; urgency=low
* Fix crash when the "mirror" method does not find any entry
(closes: #699303)

[ Johan Kiviniemi ]
* cmdline/apt-key:
- Create new keyrings with mode 0644 instead of 0600.
- Accept a nonexistent --keyring file with the adv subcommand as well.

-- Michael Vogt <mvo@debian.org> Thu, 06 Jun 2013 19:15:14 +0200

apt (0.9.8.1) unstable; urgency=low


+ 9
- 3
test/integration/framework View File

@@ -483,6 +483,7 @@ insertpackage() {
local VERSION="$4"
local DEPENDENCIES="$5"
local PRIORITY="${6:-optional}"
local DESCRIPTION="${7}"
local ARCHS=""
for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do
if [ "$arch" = 'all' -o "$arch" = 'none' ]; then
@@ -504,11 +505,16 @@ Maintainer: Joe Sixpack <joe@example.org>" >> $FILE
echo "Version: $VERSION
Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE
test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
echo -n 'Description: ' >> $FILE
if [ -z "$DESCRIPTION" ]; then
echo "an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
If you find such a package installed on your system,
YOU did something horribly wrong! They are autogenerated
und used only by testcases for APT and surf no other propose…
" >> $FILE
und used only by testcases for APT and surf no other propose…" >> $FILE
else
echo "$DESCRIPTION" >> $FILE
fi
echo >> $FILE
done
done
}


+ 33
- 0
test/integration/test-bug-691453-apt-cache-search-multi-pattern View File

@@ -0,0 +1,33 @@
#!/bin/sh
set -e

TESTDIR=$(readlink -f $(dirname $0))
. $TESTDIR/framework
setupenvironment
configarchitecture 'native'

insertpackage 'unstable' 'foobar' 'native' '1' '' '' 'funky tool'
insertpackage 'unstable' 'coolstuff' 'native' '1' '' '' 'funky tool just like foo and bar'
insertpackage 'unstable' 'foo' 'native' '1' '' '' 'tool best used with bar'
insertpackage 'unstable' 'bar' 'native' '1' '' '' 'tool best used with foo'
insertpackage 'unstable' 'baz' 'native' '1' 'Provides: bar' '' 'alternative tool best used with foo'

setupaptarchive

# in this special case the following queries should be equal
FOOBAR='foobar - funky tool
coolstuff - funky tool just like foo and bar
foo - tool best used with bar
bar - tool best used with foo
baz - alternative tool best used with foo'

testequal "$FOOBAR" aptcache search foo
testequal "$FOOBAR" aptcache search bar
testequal "$FOOBAR" aptcache search foo bar

testequal 'foobar - funky tool
foo - tool best used with bar' aptcache search -n foo
testequal 'foobar - funky tool
bar - tool best used with foo
baz - alternative tool best used with foo' aptcache search -n bar
testequal 'foobar - funky tool' aptcache search -n foo bar

Loading…
Cancel
Save