소스 검색

ENH: Make the syntax more line tar

Andy Cedilnik 20 년 전
부모
커밋
abe4fd77fc
3개의 변경된 파일159개의 추가작업 그리고 27개의 파일을 삭제
  1. 124 6
      Source/cmSystemTools.cxx
  2. 3 2
      Source/cmSystemTools.h
  3. 32 19
      Source/cmake.cxx

+ 124 - 6
Source/cmSystemTools.cxx

@@ -1363,23 +1363,72 @@ bool cmSystemTools::IsPathToFramework(const char* path)
 #  include <libtar/libtar.h>
 #  include <memory> // auto_ptr
 #  include <fcntl.h>
+#  include <cmzlib/zlib.h>
+
+static int gzopen_frontend(char *pathname, int oflags, int mode)
+{
+  char *gzoflags;
+  gzFile gzf;
+  int fd;
+
+  switch (oflags & O_ACCMODE)
+  {
+  case O_WRONLY:
+    gzoflags = "wb";
+    break;
+  case O_RDONLY:
+    gzoflags = "rb";
+    break;
+  default:
+  case O_RDWR:
+    errno = EINVAL;
+    return -1;
+  }
+
+  fd = open(pathname, oflags, mode);
+  if (fd == -1)
+    {
+    return -1;
+    }
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  if ((oflags & O_CREAT) && fchmod(fd, mode))
+    {
+    return -1;
+    }
+#endif
+
+  gzf = gzdopen(fd, gzoflags);
+  if (!gzf)
+  {
+    errno = ENOMEM;
+    return -1;
+  }
+
+  return (int)gzf;
+}
+
 #endif
 
-bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdString>& files)
+bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   TAR *t;
   char buf[TAR_MAXPATHLEN];
   char pathname[TAR_MAXPATHLEN];
 
+  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+    (readfunc_t) gzread, (writefunc_t) gzwrite
+  };
+
   // Ok, this libtar is not const safe. for now use auto_ptr hack
   char* realName = new char[ strlen(outFileName) + 1 ];
   std::auto_ptr<char> realNamePtr(realName);
   strcpy(realName, outFileName);
   if (tar_open(&t, realName,
-      NULL,
+      (gzip? &gztype : NULL),
       O_WRONLY | O_CREAT, 0644,
-      TAR_VERBOSE
+      (verbose?TAR_VERBOSE:0)
       | 0) == -1)
     {
     cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
@@ -1422,22 +1471,28 @@ bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdSt
 #endif
 }
 
-bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdString>& files)
+bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose)
 {
+  (void)files;
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   TAR *t;
+
+  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+    (readfunc_t) gzread, (writefunc_t) gzwrite
+  };
+
   // Ok, this libtar is not const safe. for now use auto_ptr hack
   char* realName = new char[ strlen(outFileName) + 1 ];
   std::auto_ptr<char> realNamePtr(realName);
   strcpy(realName, outFileName);
   if (tar_open(&t, realName,
-      NULL,
+      (gzip? &gztype : NULL),
       O_RDONLY
 #ifdef _WIN32
       | O_BINARY
 #endif
       , 0,
-      TAR_VERBOSE
+      (verbose?TAR_VERBOSE:0)
       | 0) == -1)
     {
     cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
@@ -1460,3 +1515,66 @@ bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdS
   return false;
 #endif
 }
+
+bool cmSystemTools::ListTar(const char* outFileName, std::vector<cmStdString>& files, bool gzip, bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+  TAR *t;
+
+  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+    (readfunc_t) gzread, (writefunc_t) gzwrite
+  };
+
+  // Ok, this libtar is not const safe. for now use auto_ptr hack
+  char* realName = new char[ strlen(outFileName) + 1 ];
+  std::auto_ptr<char> realNamePtr(realName);
+  strcpy(realName, outFileName);
+  if (tar_open(&t, realName,
+      (gzip? &gztype : NULL),
+      O_RDONLY
+#ifdef _WIN32
+      | O_BINARY
+#endif
+      , 0,
+      (verbose?TAR_VERBOSE:0)
+      | 0) == -1)
+    {
+    cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
+    return false;
+    }
+
+  int i;
+  while ((i = th_read(t)) == 0)
+  {
+    const char* filename = th_get_pathname(t);
+    files.push_back(filename);
+   
+    if ( verbose )
+      {
+      th_print_long_ls(t);
+      }
+    else
+      {
+      std::cout << filename << std::endl;
+      }
+
+#ifdef DEBUG
+    th_print(t);
+#endif
+    if (TH_ISREG(t) && tar_skip_regfile(t) != 0)
+      {
+      cmSystemTools::Error("Problem with tar_skip_regfile(): ", strerror(errno));
+      return false;
+      }
+  }
+
+  if (tar_close(t) != 0)
+    {
+    cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
+    return false;
+    }
+  return true;
+#else
+  return false;
+#endif
+}

+ 3 - 2
Source/cmSystemTools.h

@@ -298,8 +298,9 @@ public:
   static bool PutEnv(const char* value);
 
   /** Create tar */
-  static bool CreateTar(const char* outFileName, const std::vector<cmStdString>& files);
-  static bool ExtractTar(const char* inFileName, const std::vector<cmStdString>& files);
+  static bool ListTar(const char* outFileName, std::vector<cmStdString>& files, bool gzip, bool verbose);
+  static bool CreateTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose);
+  static bool ExtractTar(const char* inFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose);
 private:
   static bool s_ForceUnixPaths;
   static bool s_RunCommandHideConsole;

+ 32 - 19
Source/cmake.cxx

@@ -720,8 +720,7 @@ void CMakeCommandUsage(const char* program)
     << "  copy_directory source destination    - copy directory 'source' content to directory 'destination'\n"
     << "  echo [string]...        - displays arguments as text\n"
     << "  remove file1 file2 ...  - remove the file(s)\n"
-    << "  tar file.tar file/dir1 file/dir2 ... - create a tar\n"
-    << "  untar file.tar - create a tar\n"
+    << "  tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar.\n"
     << "  time command [args] ... - run command and return elapsed time\n";
 #if defined(_WIN32) && !defined(__CYGWIN__)
   errorStream
@@ -949,33 +948,47 @@ int cmake::CMakeCommand(std::vector<std::string>& args)
     // Tar files
     else if (args[1] == "tar" && args.size() > 3)
       {
-      std::string outFile = args[2];
+      std::string flags = args[2];
+      std::string outFile = args[3];
       std::vector<cmStdString> files;
-      for (std::string::size_type cc = 3; cc < args.size(); cc ++)
+      for (std::string::size_type cc = 4; cc < args.size(); cc ++)
         {
         files.push_back(args[cc]);
         }
-      if ( !cmSystemTools::CreateTar(outFile.c_str(), files) )
+      bool gzip = false;
+      bool verbose = false;
+      if ( flags.find_first_of('z') != flags.npos )
         {
-        cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
-        return 1;
+        gzip = true;
+        }
+      if ( flags.find_first_of('v') != flags.npos )
+        {
+        verbose = true;
         }
-      return 0;
-      }
 
-    // Untar files
-    else if (args[1] == "untar" && args.size() > 2)
-      {
-      std::string outFile = args[2];
-      std::vector<cmStdString> files;
-      for (std::string::size_type cc = 3; cc < args.size(); cc ++)
+      if ( flags.find_first_of('t') != flags.npos )
         {
-        files.push_back(args[cc]);
+        if ( !cmSystemTools::ListTar(outFile.c_str(), files, gzip, verbose) )
+          {
+          cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
+          return 1;
+          }
         }
-      if ( !cmSystemTools::ExtractTar(outFile.c_str(), files) )
+      else if ( flags.find_first_of('c') != flags.npos )
         {
-        cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
-        return 1;
+        if ( !cmSystemTools::CreateTar(outFile.c_str(), files, gzip, verbose) )
+          {
+          cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
+          return 1;
+          }
+        }
+      else if ( flags.find_first_of('x') != flags.npos )
+        {
+        if ( !cmSystemTools::ExtractTar(outFile.c_str(), files, gzip, verbose) )
+          {
+          cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
+          return 1;
+          }
         }
       return 0;
       }