]> git.saurik.com Git - apt.git/blobdiff - ftparchive/writer.cc
0.5.10
[apt.git] / ftparchive / writer.cc
index 7aea89317fd00b7591554c2f6e54dfd3b7bf5640..94d88388abe9d6ed0257025d7d88eff3b41dcced 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: writer.cc,v 1.2 2001/02/20 07:03:18 jgg Exp $
+// $Id: writer.cc,v 1.7 2003/02/10 07:34:41 doogie Exp $
 /* ######################################################################
 
    Writer 
@@ -17,6 +17,7 @@
 
 #include "writer.h"
     
+#include <apti18n.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <ftw.h>
+#include <iostream>
     
 #include "cachedb.h"
 #include "apt-ftparchive.h"
 #include "multicompress.h"
                                                                        /*}}}*/
 
+using namespace std;
 FTWScanner *FTWScanner::Owner;
 
+// SetTFRewriteData - Helper for setting rewrite lists                 /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+inline void SetTFRewriteData(struct TFRewriteData &tfrd,
+                            const char *tag,
+                            const char *rewrite,
+                            const char *newtag = 0)
+{
+    tfrd.Tag = tag;
+    tfrd.Rewrite = rewrite;
+    tfrd.NewTag = newtag;
+}
+                                                                       /*}}}*/
+
 // FTWScanner::FTWScanner - Constructor                                        /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -58,12 +75,12 @@ int FTWScanner::Scanner(const char *File,const struct stat *sb,int Flag)
    if (Flag == FTW_DNR)
    {
       Owner->NewLine(1);
-      c1out << "W: Unable to read directory " << File << endl;
+      ioprintf(c1out, _("W: Unable to read directory %s\n"), File);
    }   
    if (Flag == FTW_NS)
    {
       Owner->NewLine(1);
-      c1out << "W: Unable to stat " << File << endl;
+      ioprintf(c1out, _("W: Unable to stat %s\n"), File);
    }   
    if (Flag != FTW_F)
       return 0;
@@ -102,16 +119,16 @@ int FTWScanner::Scanner(const char *File,const struct stat *sb,int Flag)
         
         bool Type = _error->PopMessage(Err);
         if (Type == true)
-           c1out << "E: " << Err << endl;
+           cerr << _("E: ") << Err << endl;
         else
-           c1out << "W: " << Err << endl;
+           cerr << _("W: ") << Err << endl;
         
         if (Err.find(File) != string::npos)
            SeenPath = true;
       }      
       
       if (SeenPath == false)
-        cerr << "E: Errors apply to file '" << File << "'" << endl;
+        cerr << _("E: Errors apply to file ") << "'" << File << "'" << endl;
       return 0;
    }
    
@@ -128,7 +145,7 @@ bool FTWScanner::RecursiveScan(string Dir)
    if (InternalPrefix.empty() == true)
    {
       if (realpath(Dir.c_str(),RealPath) == 0)
-        return _error->Errno("realpath","Failed to resolve %s",Dir.c_str());
+        return _error->Errno("realpath",_("Failed to resolve %s"),Dir.c_str());
       InternalPrefix = RealPath;      
    }
    
@@ -140,7 +157,7 @@ bool FTWScanner::RecursiveScan(string Dir)
    if (Res != 0)
    {
       if (_error->PendingError() == false)
-        _error->Errno("ftw","Tree walking failed");
+        _error->Errno("ftw",_("Tree walking failed"));
       return false;
    }
    
@@ -158,14 +175,14 @@ bool FTWScanner::LoadFileList(string Dir,string File)
    if (InternalPrefix.empty() == true)
    {
       if (realpath(Dir.c_str(),RealPath) == 0)
-        return _error->Errno("realpath","Failed to resolve %s",Dir.c_str());
+        return _error->Errno("realpath",_("Failed to resolve %s"),Dir.c_str());
       InternalPrefix = RealPath;      
    }
    
    Owner = this;
    FILE *List = fopen(File.c_str(),"r");
    if (List == 0)
-      return _error->Errno("fopen","Failed to open %s",File.c_str());
+      return _error->Errno("fopen",_("Failed to open %s"),File.c_str());
    
    /* We are a tad tricky here.. We prefix the buffer with the directory
       name, that way if we need a full path with just use line.. Sneaky and
@@ -222,25 +239,26 @@ bool FTWScanner::Delink(string &FileName,const char *OriginalPath,
            cout << endl;
         
         NewLine(1);
-        c1out << " DeLink " << (OriginalPath + InternalPrefix.length())
-           << " [" << SizeToStr(St.st_size) << "B]" << endl << flush;
+        ioprintf(c1out, _(" DeLink %s [%s]\n"), (OriginalPath + InternalPrefix.length()),
+                   SizeToStr(St.st_size).c_str());
+        c1out << flush;
         
         if (NoLinkAct == false)
         {
            char OldLink[400];
            if (readlink(OriginalPath,OldLink,sizeof(OldLink)) == -1)
-              _error->Errno("readlink","Failed to readlink %s",OriginalPath);
+              _error->Errno("readlink",_("Failed to readlink %s"),OriginalPath);
            else
            {
               if (unlink(OriginalPath) != 0)
-                 _error->Errno("unlink","Failed to unlink %s",OriginalPath);
+                 _error->Errno("unlink",_("Failed to unlink %s"),OriginalPath);
               else
               {
                  if (link(FileName.c_str(),OriginalPath) != 0)
                  {
                     // Panic! Restore the symlink
                     symlink(OldLink,OriginalPath);
-                    return _error->Errno("link","*** Failed to link %s to %s",
+                    return _error->Errno("link",_("*** Failed to link %s to %s"),
                                          FileName.c_str(),
                                          OriginalPath);
                  }            
@@ -250,7 +268,7 @@ bool FTWScanner::Delink(string &FileName,const char *OriginalPath,
         
         DeLinkBytes += St.st_size;
         if (DeLinkBytes/1024 >= DeLinkLimit)
-           c1out << " DeLink limit of " << SizeToStr(DeLinkBytes) << "B hit." << endl;      
+           ioprintf(c1out, _(" DeLink limit of %sB hit.\n"), SizeToStr(DeLinkBytes).c_str());      
       }
       
       FileName = OriginalPath;
@@ -274,7 +292,7 @@ bool FTWScanner::SetExts(string Vals)
 // PackagesWriter::PackagesWriter - Constructor                                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-PackagesWriter::PackagesWriter(string DB,string Overrides) :
+PackagesWriter::PackagesWriter(string DB,string Overrides,string ExtOverrides) :
                    Db(DB),Stats(Db.Stats)
 {
    Output = stdout;
@@ -289,12 +307,16 @@ PackagesWriter::PackagesWriter(string DB,string Overrides) :
 
    if (Db.Loaded() == false)
       DoContents = false;
-       
+      
    // Read the override file
    if (Overrides.empty() == false && Over.ReadOverride(Overrides) == false)
       return;
    else
       NoOverride = true;
+
+   if (ExtOverrides.empty() == false)
+      Over.ReadExtraOverride(ExtOverrides);
+
    _error->DumpErrors();
 }
                                                                        /*}}}*/
@@ -313,7 +335,7 @@ bool PackagesWriter::DoPackage(string FileName)
    // Stat the file for later
    struct stat St;
    if (fstat(F.Fd(),&St) != 0)
-      return _error->Errno("fstat","Failed to stat %s",FileName.c_str());
+      return _error->Errno("fstat",_("Failed to stat %s"),FileName.c_str());
 
    // Pull all the data we need form the DB
    string MD5Res;
@@ -333,7 +355,7 @@ bool PackagesWriter::DoPackage(string FileName)
    Override::Item *OverItem = Over.GetItem(Package);
    
    if (Package.empty() == true)
-      return _error->Error("Archive had no package field");
+      return _error->Error(_("Archive had no package field"));
    
    // If we need to do any rewriting of the header do it now..
    if (OverItem == 0)
@@ -341,11 +363,11 @@ bool PackagesWriter::DoPackage(string FileName)
       if (NoOverride == false)
       {
         NewLine(1);
-        c1out << "  " << Package << " has no override entry" << endl;
+        ioprintf(c1out, _("  %s has no override entry\n"), Package.c_str());
       }
       
       OverItem = &Tmp;
-      Tmp.Section = Tags.FindS("Section");
+      Tmp.FieldOverride["Section"] = Tags.FindS("Section");
       Tmp.Priority = Tags.FindS("Priority");
    }
 
@@ -365,19 +387,17 @@ bool PackagesWriter::DoPackage(string FileName)
       NewFileName = flCombine(PathPrefix,NewFileName);
           
    // This lists all the changes to the fields we are going to make.
-   TFRewriteData Changes[] = {{"Size",Size},
-                              {"MD5sum",MD5Res.c_str()},
-                              {"Filename",NewFileName.c_str()},
-                              {"Section",OverItem->Section.c_str()},
-                              {"Priority",OverItem->Priority.c_str()},
-                              {"Status",0},
-                              {"Optional",0},
-                              {},  // For maintainer
-                              {},  // For Suggests
-                             {}};
+   // (7 hardcoded + maintainer + suggests + end marker)
+   TFRewriteData Changes[6+2+OverItem->FieldOverride.size()+1];
+
    unsigned int End = 0;
-   for (End = 0; Changes[End].Tag != 0; End++);
-   
+   SetTFRewriteData(Changes[End++], "Size", Size);
+   SetTFRewriteData(Changes[End++], "MD5sum", MD5Res.c_str());
+   SetTFRewriteData(Changes[End++], "Filename", NewFileName.c_str());
+   SetTFRewriteData(Changes[End++], "Priority", OverItem->Priority.c_str());
+   SetTFRewriteData(Changes[End++], "Status", 0);
+   SetTFRewriteData(Changes[End++], "Optional", 0);
+
    // Rewrite the maintainer field if necessary
    bool MaintFailed;
    string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"),MaintFailed);
@@ -386,17 +406,13 @@ bool PackagesWriter::DoPackage(string FileName)
       if (NoOverride == false)
       {
         NewLine(1);
-        c1out << "  " << Package << " maintainer is " <<
-              Tags.FindS("Maintainer") << " not " <<
-              OverItem->OldMaint << endl;
+        ioprintf(c1out, _("  %s maintainer is %s not %s\n"),
+              Package.c_str(), Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str());
       }      
    }
    
    if (NewMaint.empty() == false)
-   {
-      Changes[End].Rewrite = NewMaint.c_str();
-      Changes[End++].Tag = "Maintainer";
-   }
+      SetTFRewriteData(Changes[End++], "Maintainer", NewMaint.c_str());
    
    /* Get rid of the Optional tag. This is an ugly, ugly, ugly hack that
       dpkg-scanpackages does.. Well sort of. dpkg-scanpackages just does renaming
@@ -408,10 +424,15 @@ bool PackagesWriter::DoPackage(string FileName)
    {
       if (Tags.FindS("Suggests").empty() == false)
         OptionalStr = Tags.FindS("Suggests") + ", " + OptionalStr;
-      Changes[End].Rewrite = OptionalStr.c_str();
-      Changes[End++].Tag = "Suggests";
+      SetTFRewriteData(Changes[End++], "Suggests", OptionalStr.c_str());
    }
-   
+
+   for (map<string,string>::iterator I = OverItem->FieldOverride.begin(); 
+        I != OverItem->FieldOverride.end(); I++) 
+      SetTFRewriteData(Changes[End++],I->first.c_str(),I->second.c_str());
+
+   SetTFRewriteData(Changes[End++], 0, 0);
+
    // Rewrite and store the fields.
    if (TFRewrite(Output,Tags,TFRewritePackageOrder,Changes) == false)
       return false;
@@ -424,7 +445,8 @@ bool PackagesWriter::DoPackage(string FileName)
 // SourcesWriter::SourcesWriter - Constructor                          /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-SourcesWriter::SourcesWriter(string BOverrides,string SOverrides)
+SourcesWriter::SourcesWriter(string BOverrides,string SOverrides,
+                            string ExtOverrides)
 {
    Output = stdout;
    Ext[0] = ".dsc";
@@ -441,11 +463,12 @@ SourcesWriter::SourcesWriter(string BOverrides,string SOverrides)
       return;
    else
       NoOverride = true;
+
+   if (ExtOverrides.empty() == false)
+      SOver.ReadExtraOverride(ExtOverrides);
    
-   if (SOverrides.empty() == false && FileExists(SOverrides) == true &&
-       SOver.ReadOverride(SOverrides,true) == false)
-      return;
-//   _error->DumpErrors();
+   if (SOverrides.empty() == false && FileExists(SOverrides) == true)
+      SOver.ReadOverride(SOverrides,true);
 }
                                                                        /*}}}*/
 // SourcesWriter::DoPackage - Process a single package                 /*{{{*/
@@ -550,7 +573,7 @@ bool SourcesWriter::DoPackage(string FileName)
       if (NoOverride == false)
       {
         NewLine(1);     
-        c1out << "  " << Tags.FindS("Source") << " has no override entry" << endl;
+        ioprintf(c1out, _("  %s has no override entry\n"), Tags.FindS("Source").c_str());
       }
       
       OverItem = &Tmp;
@@ -575,17 +598,16 @@ bool SourcesWriter::DoPackage(string FileName)
    string NewFileName;
    if (DirStrip.empty() == false &&
        FileName.length() > DirStrip.length() &&
-       stringcmp(OriginalPath,OriginalPath + DirStrip.length(),
-                DirStrip.begin(),DirStrip.end()) == 0)
+       stringcmp(DirStrip,OriginalPath,OriginalPath + DirStrip.length()) == 0)
       NewFileName = string(OriginalPath + DirStrip.length());
    else 
       NewFileName = OriginalPath;
    if (PathPrefix.empty() == false)
       NewFileName = flCombine(PathPrefix,NewFileName);
-    
+
    string Directory = flNotFile(OriginalPath);
    string Package = Tags.FindS("Source");
-   
+
    // Perform the delinking operation over all of the files
    string ParseJnk;
    const char *C = Files;
@@ -612,18 +634,18 @@ bool SourcesWriter::DoPackage(string FileName)
    Directory = flNotFile(NewFileName);
    if (Directory.length() > 2)
       Directory.erase(Directory.end()-1);
-      
+
    // This lists all the changes to the fields we are going to make.
-   TFRewriteData Changes[] = {{"Source",Package.c_str(),"Package"},
-                              {"Files",Files},
-                              {"Directory",Directory.c_str()},
-                              {"Section",SOverItem->Section.c_str()},
-                              {"Priority",BestPrio.c_str()},
-                              {"Status",0},
-                              {},  // For maintainer
-                             {}};
+   // (5 hardcoded + maintainer + end marker)
+   TFRewriteData Changes[5+1+SOverItem->FieldOverride.size()+1];
+
    unsigned int End = 0;
-   for (End = 0; Changes[End].Tag != 0; End++);
+   SetTFRewriteData(Changes[End++],"Source",Package.c_str(),"Package");
+   SetTFRewriteData(Changes[End++],"Files",Files);
+   if (Directory != "./")
+      SetTFRewriteData(Changes[End++],"Directory",Directory.c_str());
+   SetTFRewriteData(Changes[End++],"Priority",BestPrio.c_str());
+   SetTFRewriteData(Changes[End++],"Status",0);
 
    // Rewrite the maintainer field if necessary
    bool MaintFailed;
@@ -633,16 +655,18 @@ bool SourcesWriter::DoPackage(string FileName)
       if (NoOverride == false)
       {
         NewLine(1);     
-        c1out << "  " << Package << " maintainer is " <<
-              Tags.FindS("Maintainer") << " not " <<
-              OverItem->OldMaint << endl;
+        ioprintf(c1out, _("  %s maintainer is %s not %s\n"), Package.c_str(),
+              Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str());
       }      
    }
    if (NewMaint.empty() == false)
-   {
-      Changes[End].Rewrite = NewMaint.c_str();
-      Changes[End++].Tag = "Maintainer";
-   }
+      SetTFRewriteData(Changes[End++], "Maintainer", NewMaint.c_str());
+   
+   for (map<string,string>::iterator I = SOverItem->FieldOverride.begin(); 
+        I != SOverItem->FieldOverride.end(); I++) 
+      SetTFRewriteData(Changes[End++],I->first.c_str(),I->second.c_str());
+
+   SetTFRewriteData(Changes[End++], 0, 0);
       
    // Rewrite and store the fields.
    if (TFRewrite(Output,Tags,TFRewriteSourceOrder,Changes) == false)