[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

apt-cache search, mutliple patterns



I got annoyed that "apt-cache search" took only one pattern, so I
patched it to accept multiple patterns (with an implicit AND condition
between the patterns). Below is my modified Search function, from
cmdline/apt-cache.cc

I'd be happy if you took this code. If not, ohwell, I'll use it
anyways. :)

// Search - Perform a search						/*{{{*/
// ---------------------------------------------------------------------
/* This searches the package names and pacakge descriptions for a pattern */
bool Search(CommandLine &CmdL)
{
   pkgCache &Cache = *GCache;
   bool ShowFull = _config->FindB("APT::Cache::ShowFull",false);
   bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false);

   int NumPatterns = CmdL.FileSize() - 1;
   // Make sure there is at least one argument
   if (NumPatterns < 1)
      return _error->Error("You must give at least one pattern");
   
   // Compile the regex patterns
   regex_t *Pattern = new regex_t[NumPatterns];

   for (int i = 0; i < NumPatterns; i++) {
       if (regcomp(&(Pattern[i]),CmdL.FileList[i+1],REG_EXTENDED | REG_ICASE | 
                   REG_NOSUB) != 0)
           return _error->Error("Regex compilation error");
   }
   
   // Create the text record parser
   pkgRecords Recs(Cache);
   if (_error->PendingError() == true)
      return false;
   
   // Search package names
   pkgCache::PkgIterator I = Cache.PkgBegin();
   for (;I.end() != true; I++)
   {
      // We search against the install version as that makes the most sense..
      pkgCache::VerIterator V = Cache.GetCandidateVer(I);
      if (V.end() == true)
	 continue;

      pkgRecords::Parser &P = Recs.Lookup(V.FileList());
    
      int IsGood = 1;
      const char *LD = P.LongDesc().c_str();

      for (int i = 0; IsGood && (i < NumPatterns); i++) 
      {
          if (NamesOnly == false)
          {
              if ((regexec(&(Pattern[i]),LD,0,0,0) != 0) 
                  && (regexec(&(Pattern[i]),I.Name(),0,0,0) != 0))
                  IsGood = 0;
          }
          else 
          {
              if (regexec(&(Pattern[i]),I.Name(),0,0,0) != 0)
                  IsGood = 0;
          }
      }

      if (IsGood)
      {
	 if (ShowFull == true)
	    DisplayRecord(V);
	 else
	    cout << I.Name() << " - " << P.ShortDesc() << endl;
      }      
   }
   
   for (int i = 0; i < NumPatterns; i++)
       regfree(&(Pattern[i]));

   delete Pattern;
       
   return true;
}
									/*}}}*/



Reply to: