summaryrefslogtreecommitdiff
path: root/cmdline
diff options
context:
space:
mode:
Diffstat (limited to 'cmdline')
-rw-r--r--cmdline/apt-cache.cc79
1 files changed, 51 insertions, 28 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index de263a300..bda09a5a1 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -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)
{