[Cmake-commits] CMake branch, next, updated. v2.8.2-381-gb0f2879

Brad King brad.king at kitware.com
Mon Aug 9 10:02:28 EDT 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  b0f287998b5b760a278adb7156aa57d69764dbd8 (commit)
       via  1b5b2ed3b2c458b25523342f3f32cb2a6368b1f5 (commit)
       via  c7c90095d4759034359a747abb1cc32b97dc8363 (commit)
       via  ac267371e63806718a0905e321baa552f18a57e9 (commit)
      from  95df1aa4d8bac88434a6f005ec8a9ea87edf4ad7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b0f287998b5b760a278adb7156aa57d69764dbd8
commit b0f287998b5b760a278adb7156aa57d69764dbd8
Merge: 95df1aa 1b5b2ed
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Aug 9 10:02:26 2010 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Aug 9 10:02:26 2010 -0400

    Merge topic 'libarchive-wrapper' into next
    
    1b5b2ed Include entries for directories in tarballs (#11020)
    c7c9009 Create class cmArchiveWrite to wrap libarchive (#11020)
    ac26737 Merge branch 'system-libarchive-include' into libarchive-wrapper


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1b5b2ed3b2c458b25523342f3f32cb2a6368b1f5
commit 1b5b2ed3b2c458b25523342f3f32cb2a6368b1f5
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Aug 6 11:33:32 2010 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Aug 6 11:38:14 2010 -0400

    Include entries for directories in tarballs (#11020)
    
    Use libarchive through class cmArchiveWrite to implement the method
    cmSystemTools::CreateTar.  The class includes entries for directories by
    automatically traversing the tree on disk.

diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 2364d7e..a26452c 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -23,6 +23,7 @@
 #include <cmsys/Directory.hxx>
 #include <cmsys/System.h>
 #if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmArchiveWrite.h"
 # include <cm_libarchive.h>
 # include <cmsys/Terminal.h>
 #endif
@@ -1718,142 +1719,40 @@ bool cmSystemTools::CreateTar(const char* outFileName,
                               bool gzip, bool bzip2, bool verbose)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  
-  // Create a macro to handle return from libarchive 
-  // functions
-#define CHECK_ARCHIVE_ERROR(res, msg)\
-   if(res != ARCHIVE_OK)\
-    {\
-    cmSystemTools::Error(msg, \
-                         archive_error_string(a));\
-    return false;\
-    }
-  
   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-  // recursively expand all directories in files so that we have a list
-  // of files
-  std::vector<std::string> expandedFiles;
+  std::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
+  if(!fout)
+    {
+    std::string e = "Cannot open output file \"";
+    e += outFileName;
+    e += "\": ";
+    e += cmSystemTools::GetLastSystemError();
+    cmSystemTools::Error(e.c_str());
+    return false;
+    }
+  cmArchiveWrite a(fout, (gzip? cmArchiveWrite::CompressGZip :
+                          (bzip2? cmArchiveWrite::CompressBZip2 :
+                           cmArchiveWrite::CompressNone)));
+  a.SetVerbose(verbose);
   for(std::vector<cmStdString>::const_iterator i = files.begin();
       i != files.end(); ++i)
     {
-    if(cmSystemTools::FileIsDirectory(i->c_str()))
+    std::string path = *i;
+    if(cmSystemTools::FileIsFullPath(path.c_str()))
       {
-      cmsys::Glob gl;
-      std::string findExpr = *i; 
-      if ( findExpr[findExpr.size()-1] != '/' )
-        {
-        findExpr +="/";
-        }
-      findExpr += "*";
-      gl.RecurseOn();
-      if ( gl.FindFiles(findExpr) )
-        {
-        std::vector<std::string> dirfiles = gl.GetFiles();
-        std::copy(dirfiles.begin(), dirfiles.end(),
-                  std::back_inserter(expandedFiles));
-        }
+      // Get the relative path to the file.
+      path = cmSystemTools::RelativePath(cwd.c_str(), path.c_str());
       }
-    else
+    if(!a.Add(path))
       {
-      if(!cmSystemTools::FileIsFullPath(i->c_str()))
-        {
-        std::string fullp = cwd + "/" + *i;
-        expandedFiles.push_back(fullp);
-        }
-      else
-        {
-        expandedFiles.push_back(*i);
-        }
+      break;
       }
     }
-  int res;
-  // create a new archive
-  struct archive* a = archive_write_new();
   if(!a)
     {
-    cmSystemTools::Error("Unable to use create archive");
+    cmSystemTools::Error(a.GetError().c_str());
     return false;
     }
-
-  if(gzip)
-    {
-    res = archive_write_set_compression_gzip(a);
-    CHECK_ARCHIVE_ERROR(res, "Can not set gzip:");
-    } 
-  if(bzip2)
-    {
-    res = archive_write_set_compression_bzip2(a); 
-    CHECK_ARCHIVE_ERROR(res, "Can not set bzip2:");
-    }
-  if(!bzip2 && !gzip)
-    { 
-    res = archive_write_set_compression_none(a); 
-    CHECK_ARCHIVE_ERROR(res, "Can not set none:");
-    }
-  res = archive_write_set_format_pax_restricted(a);
-  CHECK_ARCHIVE_ERROR(res, "Can not set tar format:");
-  res = archive_write_open_file(a, outFileName);
-  CHECK_ARCHIVE_ERROR(res, "write open:");
-    // create a new disk struct
-  struct archive* disk = archive_read_disk_new();
-  archive_read_disk_set_standard_lookup(disk);
-  std::vector<std::string>::const_iterator fileIt;
-  for ( fileIt = expandedFiles.begin(); 
-        fileIt != expandedFiles.end(); ++ fileIt )
-    {
-    // create a new entry for each file
-    struct archive_entry *entry = archive_entry_new(); 
-    // Get the relative path to the file
-    std::string rp = cmSystemTools::RelativePath(cwd.c_str(),
-                                                 fileIt->c_str());
-    if(verbose)
-      {
-      std::cout << rp << "\n";
-      }
-    // Set the name of the entry to the file name
-    archive_entry_set_pathname(entry, rp.c_str()); 
-    archive_read_disk_entry_from_file(disk, entry, -1, 0);
-    CHECK_ARCHIVE_ERROR(res, "read disk entry:");
-
-    // write  entry header
-    res = archive_write_header(a, entry);
-    CHECK_ARCHIVE_ERROR(res, "write header: ");
-    if(archive_entry_size(entry) > 0)
-      {
-      // now copy contents of file into archive a
-      FILE* file = fopen(fileIt->c_str(), "rb");
-      if(!file)
-        {
-          cmSystemTools::Error("Problem with fopen(): ",
-                               fileIt->c_str());
-          return false;
-        }
-      char buff[16384];
-      size_t len = fread(buff, 1, sizeof(buff), file);
-      while (len > 0)
-        {
-          size_t wlen = archive_write_data(a, buff, len);
-          if(wlen != len)
-            { 
-              cmOStringStream error;
-              error << "Problem with archive_write_data\n"
-                    << "Tried to write  [" << len << "] bytes.\n"
-                    << "archive_write_data wrote  [" << wlen << "] bytes.\n";
-              cmSystemTools::Error(error.str().c_str(),
-                                   archive_error_string(a)
-                                   );
-              return false;
-            }
-          len = fread(buff, 1, sizeof(buff), file);
-        }
-      // close the file and free the entry
-      fclose(file);
-      }
-    archive_entry_free(entry);
-    }
-  archive_write_close(a);
-  archive_write_finish(a);
-  archive_read_finish(disk);
   return true;
 #else
   (void)outFileName;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c7c90095d4759034359a747abb1cc32b97dc8363
commit c7c90095d4759034359a747abb1cc32b97dc8363
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Aug 6 11:38:05 2010 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Aug 6 11:38:05 2010 -0400

    Create class cmArchiveWrite to wrap libarchive (#11020)

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b098da1..71284b2 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -112,6 +112,7 @@ ENDIF(CMAKE_USE_ELF_PARSER)
 #
 SET(SRCS
   cmStandardIncludes.cxx
+  cmArchiveWrite.cxx
   cmBootstrapCommands.cxx
   cmCacheManager.cxx
   cmCacheManager.h
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
new file mode 100644
index 0000000..0a44168
--- /dev/null
+++ b/Source/cmArchiveWrite.cxx
@@ -0,0 +1,243 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmArchiveWrite.h"
+
+#include "cmSystemTools.h"
+#include <cmsys/Directory.hxx>
+#include <cm_libarchive.h>
+
+//----------------------------------------------------------------------------
+class cmArchiveWrite::Entry
+{
+  struct archive_entry* Object;
+public:
+  Entry(): Object(archive_entry_new()) {}
+  ~Entry() { archive_entry_free(this->Object); }
+  operator struct archive_entry*() { return this->Object; }
+};
+
+//----------------------------------------------------------------------------
+struct cmArchiveWrite::Callback
+{
+  // archive_write_callback
+  static __LA_SSIZE_T Write(struct archive*, void *cd,
+                            const void *b, size_t n)
+    {
+    cmArchiveWrite* self = static_cast<cmArchiveWrite*>(cd);
+    if(self->Stream.write(static_cast<const char*>(b), n))
+      {
+      return static_cast<__LA_SSIZE_T>(n);
+      }
+    else
+      {
+      return static_cast<__LA_SSIZE_T>(-1);
+      }
+    }
+};
+
+//----------------------------------------------------------------------------
+cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c):
+  Stream(os),
+  Archive(archive_write_new()),
+  Disk(archive_read_disk_new()),
+  Verbose(false)
+{
+  switch (c)
+    {
+    case CompressNone:
+      if(archive_write_set_compression_none(this->Archive) != ARCHIVE_OK)
+        {
+        this->Error = "archive_write_set_compression_none: ";
+        this->Error += archive_error_string(this->Archive);
+        return;
+        }
+      break;
+    case CompressGZip:
+      if(archive_write_set_compression_gzip(this->Archive) != ARCHIVE_OK)
+        {
+        this->Error = "archive_write_set_compression_gzip: ";
+        this->Error += archive_error_string(this->Archive);
+        return;
+        }
+      break;
+    case CompressBZip2:
+      if(archive_write_set_compression_bzip2(this->Archive) != ARCHIVE_OK)
+        {
+        this->Error = "archive_write_set_compression_bzip2: ";
+        this->Error += archive_error_string(this->Archive);
+        return;
+        }
+      break;
+    };
+  archive_read_disk_set_standard_lookup(this->Disk);
+  if(archive_write_set_format_pax_restricted(this->Archive) != ARCHIVE_OK)
+    {
+    this->Error = "archive_write_set_format_pax_restricted: ";
+    this->Error += archive_error_string(this->Archive);
+    return;
+    }
+
+  if(archive_write_open(
+       this->Archive, this, 0,
+       reinterpret_cast<archive_write_callback*>(&Callback::Write),
+       0) != ARCHIVE_OK)
+    {
+    this->Error = "archive_write_open: ";
+    this->Error += archive_error_string(this->Archive);
+    return;
+    }
+}
+
+//----------------------------------------------------------------------------
+cmArchiveWrite::~cmArchiveWrite()
+{
+  archive_read_finish(this->Disk);
+  archive_write_finish(this->Archive);
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+{
+  if(this->Okay())
+    {
+    if(!path.empty() && path[path.size()-1] == '/')
+      {
+      path.erase(path.size()-1);
+      }
+    this->AddPath(path.c_str(), skip, prefix);
+    }
+  return this->Okay();
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddPath(const char* path,
+                             size_t skip, const char* prefix)
+{
+  if(!this->AddFile(path, skip, prefix))
+    {
+    return false;
+    }
+  if(!cmSystemTools::FileIsDirectory(path))
+    {
+    return true;
+    }
+  cmsys::Directory d;
+  if(d.Load(path))
+    {
+    std::string next = path;
+    next += "/";
+    std::string::size_type end = next.size();
+    unsigned long n = d.GetNumberOfFiles();
+    for(unsigned long i = 0; i < n; ++i)
+      {
+      const char* file = d.GetFile(i);
+      if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
+        {
+        next.erase(end);
+        next += file;
+        if(!this->AddPath(next.c_str(), skip, prefix))
+          {
+          return false;
+          }
+        }
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddFile(const char* file,
+                             size_t skip, const char* prefix)
+{
+  // Skip the file if we have no name for it.  This may happen on a
+  // top-level directory, which does not need to be included anyway.
+  if(skip >= strlen(file))
+    {
+    return true;
+    }
+  const char* out = file + skip;
+
+  // Meta-data.
+  std::string dest = prefix? prefix : "";
+  dest += out;
+  if(this->Verbose)
+    {
+    std::cout << dest << "\n";
+    }
+  Entry e;
+  archive_entry_copy_sourcepath(e, file);
+  archive_entry_set_pathname(e, dest.c_str());
+  if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK)
+    {
+    this->Error = "archive_read_disk_entry_from_file: ";
+    this->Error += archive_error_string(this->Disk);
+    return false;
+    }
+  if(archive_write_header(this->Archive, e) != ARCHIVE_OK)
+    {
+    this->Error = "archive_write_header: ";
+    this->Error += archive_error_string(this->Archive);
+    return false;
+    }
+
+  // Content.
+  if(size_t size = static_cast<size_t>(archive_entry_size(e)))
+    {
+    return this->AddData(file, size);
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddData(const char* file, size_t size)
+{
+  std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+  if(!fin)
+    {
+    this->Error = "Error opening \"";
+    this->Error += file;
+    this->Error += "\": ";
+    this->Error += cmSystemTools::GetLastSystemError();
+    return false;
+    }
+
+  char buffer[16384];
+  size_t nleft = size;
+  while(nleft > 0)
+    {
+    size_t nnext = nleft > sizeof(buffer)? sizeof(buffer) : nleft;
+    fin.read(buffer, nnext);
+    // Some stream libraries (older HPUX) return failure at end of
+    // file on the last read even if some data were read.  Check
+    // gcount instead of trusting the stream error status.
+    if(fin.gcount() != nnext)
+      {
+      break;
+      }
+    if(archive_write_data(this->Archive, buffer, nnext) != nnext)
+      {
+      this->Error = "archive_write_data: ";
+      this->Error += archive_error_string(this->Archive);
+      return false;
+      }
+    nleft -= nnext;
+    }
+  if(nleft > 0)
+    {
+    this->Error = "Error reading \"";
+    this->Error += file;
+    this->Error += "\": ";
+    this->Error += cmSystemTools::GetLastSystemError();
+    return false;
+    }
+  return true;
+}
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
new file mode 100644
index 0000000..92c0c73
--- /dev/null
+++ b/Source/cmArchiveWrite.h
@@ -0,0 +1,84 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmArchiveWrite_h
+#define cmArchiveWrite_h
+
+#include "cmStandardIncludes.h"
+
+#if !defined(CMAKE_BUILD_WITH_CMAKE)
+# error "cmArchiveWrite not allowed during bootstrap build!"
+#endif
+
+/** \class cmArchiveWrite
+ * \brief Wrapper around libarchive for writing.
+ *
+ */
+class cmArchiveWrite
+{
+  typedef void (cmArchiveWrite::* safe_bool)();
+  void safe_bool_true() {}
+public:
+  /** Compression type.  */
+  enum Compress
+  {
+    CompressNone,
+    CompressGZip,
+    CompressBZip2
+  };
+
+  /** Construct with output stream to which to write archive.  */
+  cmArchiveWrite(std::ostream& os, Compress c = CompressNone);
+  ~cmArchiveWrite();
+
+  /**
+   * Add a path (file or directory) to the archive.  Directories are
+   * added recursively.  The "path" must be readable on disk, either
+   * full path or relative to current working directory.  The "skip"
+   * value indicates how many leading bytes from the input path to
+   * skip.  The remaining part of the input path is appended to the
+   * "prefix" value to construct the final name in the archive.
+   */
+  bool Add(std::string path, size_t skip = 0, const char* prefix = 0);
+
+  /** Returns true if there has been no error.  */
+  operator safe_bool() const
+    { return this->Okay()? &cmArchiveWrite::safe_bool_true : 0; }
+
+  /** Returns true if there has been an error.  */
+  bool operator!() const { return !this->Okay(); }
+
+  /** Return the error string; empty if none.  */
+  std::string GetError() const { return this->Error; }
+
+  // TODO: More general callback instead of hard-coding calls to
+  // std::cout.
+  void SetVerbose(bool v) { this->Verbose = v; }
+
+private:
+  bool Okay() const { return this->Error.empty(); }
+  bool AddPath(const char* path, size_t skip, const char* prefix);
+  bool AddFile(const char* file, size_t skip, const char* prefix);
+  bool AddData(const char* file, size_t size);
+
+  struct Callback;
+  friend struct Callback;
+
+  class Entry;
+
+  std::ostream& Stream;
+  struct archive* Archive;
+  struct archive* Disk;
+  bool Verbose;
+  std::string Error;
+};
+
+#endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ac267371e63806718a0905e321baa552f18a57e9
commit ac267371e63806718a0905e321baa552f18a57e9
Merge: 0089366 3296e6a
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Aug 5 17:12:39 2010 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Aug 5 17:12:42 2010 -0400

    Merge branch 'system-libarchive-include' into libarchive-wrapper


-----------------------------------------------------------------------

Summary of changes:
 Source/CMakeLists.txt     |    1 +
 Source/cmArchiveWrite.cxx |  243 +++++++++++++++++++++++++++++++++++++++++++++
 Source/cmArchiveWrite.h   |   84 ++++++++++++++++
 Source/cmSystemTools.cxx  |  145 ++++-----------------------
 4 files changed, 350 insertions(+), 123 deletions(-)
 create mode 100644 Source/cmArchiveWrite.cxx
 create mode 100644 Source/cmArchiveWrite.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list