فهرست منبع

Add NEWLINE_STYLE option to configure_file (#3957)

Peter Kuemmel 14 سال پیش
والد
کامیت
a087490697

+ 2 - 0
Source/CMakeLists.txt

@@ -214,6 +214,8 @@ SET(SRCS
   cmMakefileExecutableTargetGenerator.cxx
   cmMakefileLibraryTargetGenerator.cxx
   cmMakefileUtilityTargetGenerator.cxx
+  cmNewLineStyle.h
+  cmNewLineStyle.cxx
   cmOrderDirectories.cxx
   cmOrderDirectories.h
   cmPolicies.h

+ 14 - 1
Source/cmConfigureFileCommand.cxx

@@ -65,6 +65,12 @@ bool cmConfigureFileCommand
     cmSystemTools::SetFatalErrorOccured();
     return false;
     }
+  std::string errorMessage;
+  if (!this->NewLineStyle.ReadFromArguments(args, errorMessage))
+    {
+    this->SetError(errorMessage.c_str());
+    return false;
+    }
   this->CopyOnly = false;
   this->EscapeQuotes = false;
 
@@ -78,6 +84,12 @@ bool cmConfigureFileCommand
     if(args[i] == "COPYONLY")
       {
       this->CopyOnly = true;
+      if (this->NewLineStyle.IsValid())
+        {
+        this->SetError("COPYONLY could not be used in combination "
+                       "with NEWLINE_STYLE");
+        return false;
+        }
       }
     else if(args[i] == "ESCAPE_QUOTES")
       {
@@ -122,7 +134,8 @@ int cmConfigureFileCommand::ConfigureFile()
     this->OutputFile.c_str(),
     this->CopyOnly,
     this->AtOnly,
-    this->EscapeQuotes);
+    this->EscapeQuotes,
+    this->NewLineStyle);
 }
 
 

+ 9 - 2
Source/cmConfigureFileCommand.h

@@ -56,7 +56,8 @@ public:
     {
       return
         "  configure_file(<input> <output>\n"
-        "                 [COPYONLY] [ESCAPE_QUOTES] [@ONLY])\n"
+        "                 [COPYONLY] [ESCAPE_QUOTES] [@ONLY] \n"
+        "                 [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])\n"
         "Copies a file <input> to file <output> and substitutes variable "
         "values referenced in the file content.  "
         "If <input> is a relative path it is evaluated with respect to "
@@ -81,14 +82,20 @@ public:
         "either #define VAR or /* #undef VAR */ depending on "
         "the setting of VAR in CMake. Any occurrences of #cmakedefine01 VAR "
         "will be replaced with either #define VAR 1 or #define VAR 0 "
-        "depending on whether VAR evaluates to TRUE or FALSE in CMake";
+        "depending on whether VAR evaluates to TRUE or FALSE in CMake.\n"
+        "With NEWLINE_STYLE the line ending could be adjusted: \n"
+        "    'UNIX' or 'LF' for \\n, 'DOS', 'WIN32' or 'CRLF' for \\r\\n.\n"
+        "COPYONLY must not be used with NEWLINE_STYLE.\n";
     }
 
   virtual void FinalPass();
   virtual bool HasFinalPass() const { return !this->Immediate; }
+
 private:
   int ConfigureFile();
   
+  cmNewLineStyle NewLineStyle;
+
   std::string InputFile;
   std::string OutputFile;
   bool CopyOnly;

+ 15 - 3
Source/cmMakefile.cxx

@@ -3213,7 +3213,8 @@ void cmMakefile::ConfigureString(const std::string& input,
 }
 
 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
-                              bool copyonly, bool atOnly, bool escapeQuotes)
+                              bool copyonly, bool atOnly, bool escapeQuotes,
+                              const cmNewLineStyle& newLine)
 {
   int res = 1;
   if ( !this->CanIWriteThisFile(outfile) )
@@ -3250,9 +3251,20 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
     }
   else
     {
+    std::string newLineCharacters;
+    std::ios_base::openmode omode = std::ios_base::out | std::ios_base::trunc;
+    if (newLine.IsValid())
+      {
+      newLineCharacters = newLine.GetCharacters();
+      omode |= std::ios::binary;
+      }
+    else
+      {
+      newLineCharacters = "\n";
+      }
     std::string tempOutputFile = soutfile;
     tempOutputFile += ".tmp";
-    std::ofstream fout(tempOutputFile.c_str());
+    std::ofstream fout(tempOutputFile.c_str(), omode);
     if(!fout)
       {
       cmSystemTools::Error(
@@ -3277,7 +3289,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
       {
       outLine = "";
       this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
-      fout << outLine.c_str() << "\n";
+      fout << outLine.c_str() << newLineCharacters;
       }
     // close the files before attempting to copy
     fin.close();

+ 4 - 1
Source/cmMakefile.h

@@ -19,6 +19,7 @@
 #include "cmPropertyMap.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
+#include "cmNewLineStyle.h"
 #include "cmake.h"
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -703,7 +704,9 @@ public:
    * Copy file but change lines acording to ConfigureString
    */
   int ConfigureFile(const char* infile, const char* outfile,
-                    bool copyonly, bool atOnly, bool escapeQuotes);
+                    bool copyonly, bool atOnly, bool escapeQuotes,
+                    const cmNewLineStyle& = cmNewLineStyle());
+
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   /**

+ 95 - 0
Source/cmNewLineStyle.cxx

@@ -0,0 +1,95 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2011 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 "cmNewLineStyle.h"
+
+
+
+cmNewLineStyle::cmNewLineStyle() : NewLineStyle(Invalid)
+{
+}
+
+
+bool cmNewLineStyle::IsValid() const
+{
+  return NewLineStyle != Invalid;
+}
+
+
+bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
+                                       std::string& errorString)
+{
+  NewLineStyle = Invalid;
+
+  for (size_t i = 0; i< args.size(); i++)
+    {
+    if (args[i] == "NEWLINE_STYLE")
+      {
+      size_t const styleIndex = i + 1;
+      if (args.size() > styleIndex)
+        {
+        const std::string eol = args[styleIndex];
+        if (eol == "LF" || eol == "UNIX")
+          {
+          NewLineStyle = LF;
+          return true;
+          }
+        else if (eol == "CRLF" || eol == "WIN32" || eol == "DOS")
+          {
+          NewLineStyle = CRLF;
+          return true;
+          }
+        else
+          {
+          errorString = "NEWLINE_STYLE sets an unknown style, only LF, "
+                        "CRLF, UNIX, DOS, and WIN32 are supported";
+          return false;
+          }
+        }
+      else
+        {
+        errorString = "NEWLINE_STYLE must set a style: "
+                      "LF, CRLF, UNIX, DOS, or WIN32";
+        return false;
+        }
+      }
+    }
+  return true;
+}
+
+
+const std::string cmNewLineStyle::GetCharacters() const
+{
+  switch (NewLineStyle)
+    {
+    case Invalid:
+      return "";
+    case LF:
+      return "\n";
+    case CRLF:
+      return "\r\n";
+    default:
+      ;
+    };
+  return "";
+}
+
+
+void cmNewLineStyle::SetStyle(Style style)
+{
+  NewLineStyle = style;
+}
+
+
+cmNewLineStyle::Style cmNewLineStyle::GetStyle() const
+{
+  return NewLineStyle;
+}

+ 48 - 0
Source/cmNewLineStyle.h

@@ -0,0 +1,48 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2011 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 cmNewLineStyle_h
+#define cmNewLineStyle_h
+
+#include <string>
+#include <vector>
+
+
+class cmNewLineStyle
+{
+public:
+
+  cmNewLineStyle();
+
+  enum Style
+  {
+    Invalid,
+               // LF = '\n', 0x0A, 10
+               // CR = '\r', 0x0D, 13
+    LF,        // Unix
+    CRLF,      // Dos
+  };
+
+  void SetStyle(Style);
+  Style GetStyle() const;
+
+  bool IsValid() const;
+
+  bool ReadFromArguments(const std::vector<std::string>& args,
+                         std::string &errorString);
+
+  const std::string GetCharacters() const;
+
+private:
+  Style NewLineStyle;
+};
+
+#endif

+ 3 - 0
Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake

@@ -0,0 +1,3 @@
+set(file_name  ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out COPYONLY NEWLINE_STYLE DOS)

+ 3 - 0
Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake

@@ -0,0 +1,3 @@
+set(file_name  ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out NEWLINE_STYLE)

+ 17 - 0
Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake

@@ -0,0 +1,17 @@
+set(file_name  ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
+
+function(test_eol style in out)
+    file(WRITE ${file_name} "${in}")
+    configure_file(${file_name} ${file_name}.out NEWLINE_STYLE ${style})
+    file(READ ${file_name}.out new HEX)
+    if(NOT "${new}" STREQUAL "${out}")
+        message(FATAL_ERROR "No ${style} line endings")
+    endif()
+endfunction()
+
+test_eol(DOS   "a\n" "610d0a")
+test_eol(WIN32 "b\n" "620d0a")
+test_eol(CRLF  "c\n" "630d0a")
+
+test_eol(UNIX  "d\n" "640a")
+test_eol(LF    "e\n" "650a")

+ 3 - 0
Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake

@@ -0,0 +1,3 @@
+set(file_name  ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out NEWLINE_STYLE FOO)

+ 12 - 0
Tests/CMakeTests/ConfigureFileTest.cmake.in

@@ -6,6 +6,14 @@ set(Relative-RESULT 0)
 set(Relative-STDERR "Relative test file")
 set(BadArg-RESULT 1)
 set(BadArg-STDERR "called with incorrect number of arguments")
+set(NewLineStyle-NoArg-RESULT 1)
+set(NewLineStyle-NoArg-STDERR "NEWLINE_STYLE must set a style:")
+set(NewLineStyle-WrongArg-RESULT 1)
+set(NewLineStyle-WrongArg-STDERR "NEWLINE_STYLE sets an unknown style")
+set(NewLineStyle-ValidArg-RESULT 0)
+set(NewLineStyle-ValidArg-STDERR )
+set(NewLineStyle-COPYONLY-RESULT 1)
+set(NewLineStyle-COPYONLY-STDERR "COPYONLY could not be used in combination")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(ConfigureFile
@@ -13,4 +21,8 @@ check_cmake_test(ConfigureFile
   DirOutput
   Relative
   BadArg
+  NewLineStyle-NoArg
+  NewLineStyle-WrongArg
+  NewLineStyle-ValidArg
+  NewLineStyle-COPYONLY
   )