Browse Source

configure_file: Add support for indented cmakedefine

Optional spaces and/or tabs are now understood between the '#' character
and the 'cmakedefine'/'cmakedefine01' words. This indentation is
preserved in the output lines.

Fixes: #13037
Sylvain Joubert 8 years ago
parent
commit
58f4744821

+ 12 - 0
Help/command/configure_file.rst

@@ -30,6 +30,18 @@ a false constant by the :command:`if` command.  The "..." content on the
 line after the variable name, if any, is processed as above.
 Input file lines of the form ``#cmakedefine01 VAR`` will be replaced with
 either ``#define VAR 1`` or ``#define VAR 0`` similarly.
+The result lines (with the exception of the ``#undef`` comments) can be
+indented using spaces and/or tabs between the ``#`` character
+and the ``cmakedefine`` or ``cmakedefine01`` words. This whitespace
+indentation will be preserved in the output lines::
+
+  #  cmakedefine VAR
+  #  cmakedefine01 VAR
+
+will be replaced, if ``VAR`` is defined, with::
+
+  #  define VAR
+  #  define VAR 1
 
 If the input file is modified the build system will re-run CMake to
 re-configure the file and generate the build system again.

+ 7 - 0
Help/release/dev/indented_cmakedefine.rst

@@ -0,0 +1,7 @@
+indented_cmakedefine
+--------------------
+
+* The :command:`configure_file` command learned to support indented
+  ``#  cmakedefine`` and ``#  cmakedefine01``. Spaces and/or tabs between
+  the ``#`` character and the ``cmakedefine``/``cmakedefine01`` words
+  are now understood and preserved in the output.

+ 11 - 7
Source/cmMakefile.cxx

@@ -66,8 +66,8 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
 
   this->DefineFlags = " ";
 
-  this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
-  this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
+  this->cmDefineRegex.compile("#([ \t]*)cmakedefine[ \t]+([A-Za-z_0-9]*)");
+  this->cmDefine01Regex.compile("#([ \t]*)cmakedefine01[ \t]+([A-Za-z_0-9]*)");
   this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
   this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
 
@@ -3433,18 +3433,22 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
 
     // Replace #cmakedefine instances.
     if (this->cmDefineRegex.find(line)) {
-      const char* def = this->GetDefinition(this->cmDefineRegex.match(1));
+      const char* def = this->GetDefinition(this->cmDefineRegex.match(2));
       if (!cmSystemTools::IsOff(def)) {
-        cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
+        const std::string indentation = this->cmDefineRegex.match(1);
+        cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine",
+                                     "#" + indentation + "define");
         output += line;
       } else {
         output += "/* #undef ";
-        output += this->cmDefineRegex.match(1);
+        output += this->cmDefineRegex.match(2);
         output += " */";
       }
     } else if (this->cmDefine01Regex.find(line)) {
-      const char* def = this->GetDefinition(this->cmDefine01Regex.match(1));
-      cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
+      const std::string indentation = this->cmDefine01Regex.match(1);
+      const char* def = this->GetDefinition(this->cmDefine01Regex.match(2));
+      cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01",
+                                   "#" + indentation + "define");
       output += line;
       if (!cmSystemTools::IsOff(def)) {
         output += " 1";

+ 2 - 0
Tests/Complex/CMakeLists.txt

@@ -356,6 +356,8 @@ endwhile()
 
 set(SHOULD_BE_ZERO )
 set(SHOULD_BE_ONE 1)
+set(SHOULD_BE_ZERO_AND_INDENTED )
+set(SHOULD_BE_ONE_AND_INDENTED 1)
 
 # test elseif functionality, the mess below tries to catch problem
 # of clauses being executed early or late etc

+ 22 - 0
Tests/Complex/Executable/complex.cxx

@@ -261,6 +261,12 @@ int main()
   cmPassed("ONE_VAR is defined.");
 #endif
 
+#ifndef ONE_VAR_AND_INDENTED
+  cmFailed("cmakedefine is broken, ONE_VAR_AND_INDENTED is not defined.");
+#else
+  cmPassed("ONE_VAR_AND_INDENTED is defined.");
+#endif
+
 #ifndef ONE_VAR_IS_DEFINED
   cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, "
            "ONE_VAR_IS_DEFINED is not defined.");
@@ -274,6 +280,12 @@ int main()
   cmPassed("ZERO_VAR is not defined.");
 #endif
 
+#ifdef ZERO_VAR_AND_INDENTED
+  cmFailed("cmakedefine is broken, ZERO_VAR_AND_INDENTED is defined.");
+#else
+  cmPassed("ZERO_VAR_AND_INDENTED is not defined.");
+#endif
+
 #ifndef STRING_VAR
   cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined.");
 #else
@@ -1030,6 +1042,16 @@ int main()
   } else {
     cmFailed("cmakedefine01 is not working for 1");
   }
+  if (SHOULD_BE_ZERO_AND_INDENTED == 0) {
+    cmPassed("cmakedefine01 is working for 0 and indented");
+  } else {
+    cmFailed("cmakedefine01 is not working for 0 and indented");
+  }
+  if (SHOULD_BE_ONE_AND_INDENTED == 1) {
+    cmPassed("cmakedefine01 is working for 1 and indented");
+  } else {
+    cmFailed("cmakedefine01 is not working for 1 and indented");
+  }
 #ifdef FORCE_TEST
   cmFailed("CMake SET CACHE FORCE");
 #else

+ 2 - 0
Tests/Complex/VarTests.cmake

@@ -2,6 +2,7 @@
 # Test SET
 #
 set (ZERO_VAR 0)
+set (ZERO_VAR_AND_INDENTED 0)
 set (ZERO_VAR2 0)
 
 if(ZERO_VAR)
@@ -11,6 +12,7 @@ else()
 endif()
 
 set(ONE_VAR 1)
+set(ONE_VAR_AND_INDENTED 1)
 set(ONE_VAR2 1)
 set(STRING_VAR "CMake is great" CACHE STRING "test a cache variable")
 

+ 4 - 0
Tests/Complex/cmTestConfigure.h.in

@@ -1,8 +1,10 @@
 // Test SET, VARIABLE_REQUIRES
 
 #cmakedefine ONE_VAR
+#  cmakedefine ONE_VAR_AND_INDENTED
 #cmakedefine ONE_VAR_IS_DEFINED
 #cmakedefine ZERO_VAR
+#  cmakedefine ZERO_VAR_AND_INDENTED
 
 #define STRING_VAR "${STRING_VAR}"
 
@@ -32,6 +34,8 @@
 
 #cmakedefine01 SHOULD_BE_ZERO
 #cmakedefine01 SHOULD_BE_ONE
+#  cmakedefine01 SHOULD_BE_ZERO_AND_INDENTED
+#  cmakedefine01 SHOULD_BE_ONE_AND_INDENTED
 // Needed to check for files
 
 #define BINARY_DIR "${Complex_BINARY_DIR}"

+ 2 - 0
Tests/ComplexOneConfig/CMakeLists.txt

@@ -313,6 +313,8 @@ endwhile()
 
 set(SHOULD_BE_ZERO )
 set(SHOULD_BE_ONE 1)
+set(SHOULD_BE_ZERO_AND_INDENTED )
+set(SHOULD_BE_ONE_AND_INDENTED 1)
 
 # test elseif functionality, the mess below tries to catch problem
 # of clauses being executed early or late etc

+ 22 - 0
Tests/ComplexOneConfig/Executable/complex.cxx

@@ -261,6 +261,12 @@ int main()
   cmPassed("ONE_VAR is defined.");
 #endif
 
+#ifndef ONE_VAR_AND_INDENTED
+  cmFailed("cmakedefine is broken, ONE_VAR_AND_INDENTED is not defined.");
+#else
+  cmPassed("ONE_VAR_AND_INDENTED is defined.");
+#endif
+
 #ifndef ONE_VAR_IS_DEFINED
   cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, "
            "ONE_VAR_IS_DEFINED is not defined.");
@@ -274,6 +280,12 @@ int main()
   cmPassed("ZERO_VAR is not defined.");
 #endif
 
+#ifdef ZERO_VAR_AND_INDENTED
+  cmFailed("cmakedefine is broken, ZERO_VAR_AND_INDENTED is defined.");
+#else
+  cmPassed("ZERO_VAR_AND_INDENTED is not defined.");
+#endif
+
 #ifndef STRING_VAR
   cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined.");
 #else
@@ -1030,6 +1042,16 @@ int main()
   } else {
     cmFailed("cmakedefine01 is not working for 1");
   }
+  if (SHOULD_BE_ZERO_AND_INDENTED == 0) {
+    cmPassed("cmakedefine01 is working for 0 and indented");
+  } else {
+    cmFailed("cmakedefine01 is not working for 0 and indented");
+  }
+  if (SHOULD_BE_ONE_AND_INDENTED == 1) {
+    cmPassed("cmakedefine01 is working for 1 and indented");
+  } else {
+    cmFailed("cmakedefine01 is not working for 1 and indented");
+  }
 #ifdef FORCE_TEST
   cmFailed("CMake SET CACHE FORCE");
 #else

+ 2 - 0
Tests/ComplexOneConfig/VarTests.cmake

@@ -2,6 +2,7 @@
 # Test SET
 #
 set (ZERO_VAR 0)
+set (ZERO_VAR_AND_INDENTED 0)
 set (ZERO_VAR2 0)
 
 if(ZERO_VAR)
@@ -11,6 +12,7 @@ else()
 endif()
 
 set(ONE_VAR 1)
+set(ONE_VAR_AND_INDENTED 1)
 set(ONE_VAR2 1)
 set(STRING_VAR "CMake is great" CACHE STRING "test a cache variable")
 

+ 4 - 0
Tests/ComplexOneConfig/cmTestConfigure.h.in

@@ -1,8 +1,10 @@
 // Test SET, VARIABLE_REQUIRES
 
 #cmakedefine ONE_VAR
+#  cmakedefine ONE_VAR_AND_INDENTED
 #cmakedefine ONE_VAR_IS_DEFINED
 #cmakedefine ZERO_VAR
+#  cmakedefine ZERO_VAR_AND_INDENTED
 
 #define STRING_VAR "${STRING_VAR}"
 
@@ -32,6 +34,8 @@
 
 #cmakedefine01 SHOULD_BE_ZERO
 #cmakedefine01 SHOULD_BE_ONE
+#  cmakedefine01 SHOULD_BE_ZERO_AND_INDENTED
+#  cmakedefine01 SHOULD_BE_ONE_AND_INDENTED
 // Needed to check for files
 
 #define BINARY_DIR "${Complex_BINARY_DIR}"