[cmake-commits] hoffman committed CMakeLists.txt 1.391 1.392 cmFileCommand.cxx 1.96 1.97 cmFileCommand.h 1.32 1.33

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Feb 6 09:35:04 EST 2008


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv23101/Source

Modified Files:
	CMakeLists.txt cmFileCommand.cxx cmFileCommand.h 
Log Message:
ENH: add DOWNLOAD option to FILE command


Index: cmFileCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- cmFileCommand.h	23 Jan 2008 15:27:59 -0000	1.32
+++ cmFileCommand.h	6 Feb 2008 14:35:02 -0000	1.33
@@ -84,6 +84,7 @@
       "  file(RELATIVE_PATH variable directory file)\n"
       "  file(TO_CMAKE_PATH path result)\n"
       "  file(TO_NATIVE_PATH path result)\n"
+      "  file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log])\n"
       "WRITE will write a message into a file called 'filename'. It "
       "overwrites the file if it already exists, and creates the file "
       "if it does not exist.\n"
@@ -145,7 +146,12 @@
       " one argument.\n"
       "TO_NATIVE_PATH works just like TO_CMAKE_PATH, but will convert from "
       " a cmake style path into the native path style \\ for windows and / "
-      "for UNIX.";
+      "for UNIX.\n"
+      "DOWNLOAD will download the givin URL to the given file. "
+      "If LOG var is specified a log of the download will be put in var. "
+      "If STATUS var is specified the status of the operation will"
+      " be put in var. If TIMEOUT time is specified, the operation will "
+      "timeout after time seconds, time can be specified as a float.\n";
     }
 
   cmTypeMacro(cmFileCommand, cmCommand);
@@ -180,6 +186,7 @@
                  const std::vector<std::string>& files,
                  const bool optional
                 );
+  bool HandleDownloadCommand(std::vector<std::string> const& args);
   void GetTargetTypeFromString(const std::string& stype, int& itype) const;
   bool HandleInstallDestination(cmFileInstaller& installer,
                                 std::string& destination);

Index: CMakeLists.txt
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CMakeLists.txt,v
retrieving revision 1.391
retrieving revision 1.392
diff -u -d -r1.391 -r1.392
--- CMakeLists.txt	6 Feb 2008 04:10:41 -0000	1.391
+++ CMakeLists.txt	6 Feb 2008 14:35:02 -0000	1.392
@@ -267,7 +267,8 @@
 ADD_LIBRARY(CMakeLib ${SRCS})
 TARGET_LINK_LIBRARIES(CMakeLib cmsys
   ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
-  ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES})
+  ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES}
+  ${CMAKE_CURL_LIBRARIES})
 
 # On Apple we need Carbon
 IF(APPLE)

Index: cmFileCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.cxx,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -d -r1.96 -r1.97
--- cmFileCommand.cxx	23 Jan 2008 15:27:59 -0000	1.96
+++ cmFileCommand.cxx	6 Feb 2008 14:35:02 -0000	1.97
@@ -19,6 +19,11 @@
 #include "cmHexFileConverter.h"
 #include "cmFileTimeComparison.h"
 
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_curl.h"
+#endif
+
+#undef GetCurrentDirectory
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -71,6 +76,10 @@
     {
     return this->HandleWriteCommand(args, true);
     }
+  else if ( subCommand == "DOWNLOAD" )
+    {
+    return this->HandleDownloadCommand(args);
+    }
   else if ( subCommand == "READ" )
     {
     return this->HandleReadCommand(args);
@@ -1869,5 +1878,168 @@
   this->Makefile->AddDefinition(var, value.c_str());
   return true;
 }
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+
+// Stuff for curl download
+typedef std::vector<char> cmFileCommandVectorOfChar;
+namespace{
+  size_t
+  cmFileCommandWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
+                                          void *data)
+  { 
+    register int realsize = (int)(size * nmemb);
+    std::ofstream* fout = static_cast<std::ofstream*>(data);
+    const char* chPtr = static_cast<char*>(ptr);
+    fout->write(chPtr, realsize);
+    return realsize;
+  }
+  
+  static size_t
+  cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
+                                        size_t size, void *data)
+  {
+    cmFileCommandVectorOfChar *vec
+      = static_cast<cmFileCommandVectorOfChar*>(data);
+    vec->insert(vec->end(), chPtr, chPtr + size);
+    
+    return size;
+  }
+  
+  
+}
+
+#endif
+
+bool 
+cmFileCommand::HandleDownloadCommand(std::vector<std::string> 
+                                     const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+  std::vector<std::string>::const_iterator i = args.begin();
+  if(args.size() < 3)
+    {
+    std::cout << args.size() << "\n";
+    this->SetError("FILE(DOWNLOAD url file) must be called with "
+                   "at least three arguments.");
+    return false;
+    }
+  i++; // Get rid of subcommand
+  std::string url = *i;
+  i++;
+  std::string file = *i;
+  i++;
+  double timeout = 0;
+  std::string verboseLog;
+  std::string statusVar;
+  while(i != args.end())
+    {
+    if(*i == "TIMEOUT")
+      {
+      i++;
+      if(i != args.end())
+        {
+        timeout = atof(i->c_str());
+        }
+      else
+        { 
+        this->SetError("FILE(DOWNLOAD url file TIMEOUT time) missing "
+                       "time for TIMEOUT.");
+        return false;
+        }
+      }
+    else if(*i == "LOG")
+      {
+      i++;
+      if( i == args.end())
+        {
+        this->SetError("FILE(DOWNLOAD url file LOG VAR) missing "
+                       "VAR for LOG.");
+        return false;
+        }
+      verboseLog = *i;
+      }
+    else if(*i == "STATUS")
+      {
+      i++;
+      if( i == args.end())
+        {
+        this->SetError("FILE(DOWNLOAD url file STATUS VAR) missing "
+                       "VAR for STATUS.");
+        return false;
+        }
+      statusVar = *i;
+      }
+    i++;
+    }
+  std::cout << "log var: [" << verboseLog << "]\n"; 
+  std::cout << "Url: [" << url << "]\n";
+  std::cout << "file: [" << file << "]\n";
+  std::cout << "timeout: [" << timeout << "]\n";
 
+  std::ofstream fout(file.c_str());
+  if(!fout)
+    {
+    this->SetError("FILE(DOWNLOAD url file TIMEOUT time) can not open "
+                       "file for write.");
+    return false;
+    }
+  CURL *curl;
+  curl_global_init(CURL_GLOBAL_DEFAULT);
+  curl = curl_easy_init();
+  if(!curl)
+    {
+    this->SetError("FILE(DOWNLOAD ) error "
+                   "initializing curl.");
+    return false;
+    }
+  
+  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
+                   cmFileCommandWriteMemoryCallback);
+  curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+                   cmFileCommandCurlDebugCallback);
+  cmFileCommandVectorOfChar chunkDebug;
+  ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&fout);
+  ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+  if(verboseLog.size())
+    {
+    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+    }
+  if(timeout > 0)
+    {
+    curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout ); 
+    }
+  CURLcode res = curl_easy_perform(curl);
+  std::cout << "res = " << res << "\n";
+  /* always cleanup */
+  curl_easy_cleanup(curl);
+  if(statusVar.size())
+    {
+    this->Makefile->AddDefinition(statusVar.c_str(),
+                                  curl_easy_strerror(res));
+    }
+  curl_global_cleanup();
+  if(chunkDebug.size())
+    {
+    chunkDebug.push_back(0);
+    if(CURLE_OPERATION_TIMEOUTED == res)
+      { 
+      std::string output = &*chunkDebug.begin();
+      
+      if(verboseLog.size())
+        {
+        this->Makefile->AddDefinition(verboseLog.c_str(),
+                                      &*chunkDebug.begin());
+        }
+      }
 
+    this->Makefile->AddDefinition(verboseLog.c_str(),
+                                  &*chunkDebug.begin());
+    }
+  return true;
+#else 
+  this->SetError("FILE(DOWNLOAD ) "
+                 "not supported in bootstrap cmake ");
+  return false;
+#endif  
+}



More information about the Cmake-commits mailing list