From 091e95f26dba82131de135dce5b14a937b68d92c Mon Sep 17 00:00:00 2001
From: Bill Hoffman <bill.hoffman@kitware.com>
Date: Tue, 30 Oct 2001 14:05:07 -0500
Subject: ENH: add an option to configure file command that allows for only
 expansion of at variables and not dollar variables

---
 Source/cmConfigureFileCommand.cxx |  9 ++++++--
 Source/cmConfigureFileCommand.h   |  7 ++++--
 Source/cmMakefile.cxx             | 48 ++++++++++++++++++++++++++++-----------
 Source/cmMakefile.h               |  5 ++--
 4 files changed, 50 insertions(+), 19 deletions(-)

diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index c30a63b..8792a46 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -53,6 +53,7 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args)
   m_CopyOnly = false;
   m_EscapeQuotes = false;
   m_Immediate = false;
+  m_AtOnly = false;
   for(unsigned int i=2;i < args.size();++i)
     {
     if(args[i] == "COPYONLY")
@@ -63,6 +64,10 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args)
       {
       m_EscapeQuotes = true;
       }
+    else if(args[i] == "@ONLY")
+      {
+      m_AtOnly = true;
+      }
     else if(args[i] == "IMMEDIATE")
       {
       m_Immediate = true;
@@ -136,8 +141,8 @@ void cmConfigureFileCommand::ConfigureFile()
       if(fin)
         {
         inLine = buffer;
-        m_Makefile->ExpandVariablesInString(inLine, m_EscapeQuotes);
-        m_Makefile->RemoveVariablesInString(inLine);
+        m_Makefile->ExpandVariablesInString(inLine, m_EscapeQuotes, m_AtOnly);
+        m_Makefile->RemoveVariablesInString(inLine, m_AtOnly);
         // look for special cmakedefine symbol and handle it
         // is the symbol defined
         if (cmdefine.find(inLine))
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index b052ffa..3f7befc 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -77,7 +77,7 @@ public:
   virtual const char* GetFullDocumentation()
     {
       return
-        "CONFIGURE_FILE(InputFile OutputFile [COPYONLY] [ESCAPE_QUOTES] [IMMEDIATE])\n"
+        "CONFIGURE_FILE(InputFile OutputFile [COPYONLY] [ESCAPE_QUOTES] [IMMEDIATE] [@ONLY])\n"
 	"The Input and Ouput files have to have full paths.\n"
 	"They can also use variables like CMAKE_BINARY_DIR,CMAKE_SOURCE_DIR. "
         "This command replaces any variables in the input file with their "
@@ -87,7 +87,9 @@ public:
         "passed in then any substitued quotes will be C style escaped. "
         "If IMMEDIATE is specified, then the file will be configured with "
         "the current values of CMake variables instead of waiting until the "
-        "end of CMakeLists processing.";
+        "end of CMakeLists processing.  If @ONLY is present, only variables "
+        "of the form @var@ will be replaces and ${var} will be ignored. "
+        "This is useful for configuring tcl scripts that use ${var}.";
     }
 
   virtual void FinalPass();
@@ -99,6 +101,7 @@ private:
   bool m_CopyOnly;
   bool m_EscapeQuotes;
   bool m_Immediate;
+  bool m_AtOnly;
 };
 
 
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 760fe36..e1c94da 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -884,7 +884,8 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source) const
 }
 
 const char *cmMakefile::ExpandVariablesInString(std::string& source,
-                                         bool escapeQuotes) const
+                                                bool escapeQuotes,
+                                                bool atOnly) const
 {
   // This method replaces ${VAR} and @VAR@ where VAR is looked up
   // in the m_Definitions map, if not found in the map, nothing is expanded.
@@ -892,7 +893,15 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
   // the current environment variables.
 
   // start by look for $ or @ in the string
-  std::string::size_type markerPos = source.find_first_of("$@");
+  std::string::size_type markerPos;
+  if(atOnly)
+    {
+    markerPos = source.find_first_of("@");
+    }
+  else
+    {
+    markerPos = source.find_first_of("$@");
+    }
   // if not found, or found as the last character, then leave quickly as
   // nothing needs to be expanded
   if((markerPos == std::string::npos) || (markerPos >= source.size()-1))
@@ -910,7 +919,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
     result += source.substr(currentPos, markerPos - currentPos);
     char endVariableMarker;     // what is the end of the variable @ or }
     int markerStartSize = 1;    // size of the start marker 1 or 2 or 5
-    if(source[markerPos] == '$')
+    if(!atOnly && source[markerPos] == '$')
       {
       // ${var} case
       if(source[markerPos+1] == '{')
@@ -1017,27 +1026,40 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
         currentPos = endVariablePos+1;
         }
       }
-    markerPos = source.find_first_of("$@", currentPos);
+    if(atOnly)
+      {
+      markerPos = source.find_first_of("@", currentPos);
+      }
+    else
+      {
+      markerPos = source.find_first_of("$@", currentPos);
+      }
     }
   result += source.substr(currentPos); // pick up the rest of the string
   source = result;
   return source.c_str();
 }
 
-void cmMakefile::RemoveVariablesInString(std::string& source) const
+void cmMakefile::RemoveVariablesInString(std::string& source,
+                                         bool atOnly) const
 {
-  cmRegularExpression var("(\\${[A-Za-z_0-9]*})");
-  while (var.find(source))
+  if(!atOnly)
     {
-    source.erase(var.start(),var.end() - var.start());
+    cmRegularExpression var("(\\${[A-Za-z_0-9]*})");
+    while (var.find(source))
+      {
+      source.erase(var.start(),var.end() - var.start());
+      }
     }
-
-  cmRegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
-  while (varb.find(source))
+  
+  if(!atOnly)
     {
-    source.erase(varb.start(),varb.end() - varb.start());
+    cmRegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
+    while (varb.find(source))
+      {
+      source.erase(varb.start(),varb.end() - varb.start());
+      }
     }
-
   cmRegularExpression var2("(@[A-Za-z_0-9]*@)");
   while (var2.find(source))
     {
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 532fadd..60d028e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -511,13 +511,14 @@ public:
    * expanded to match autoconf style expansions.
    */
   const char *ExpandVariablesInString(std::string& source) const;
-  const char *ExpandVariablesInString(std::string& source, bool escapeQuotes) const;
+  const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
+                                      bool atOnly = false) const;
 
   /**
    * Remove any remaining variables in the string. Anything with ${var} or
    * @var@ will be removed.  
    */
-  void RemoveVariablesInString(std::string& source) const;
+  void RemoveVariablesInString(std::string& source, bool atOnly = false) const;
 
   /**
    * Expand variables in the makefiles ivars such as link directories etc
-- 
cgit v0.12