[cmake-commits] hoffman committed cmCommandArgumentParserHelper.cxx 1.17 1.18 cmCommandArgumentParserHelper.h 1.9 1.10 cmMakefile.cxx 1.371 1.372

cmake-commits at cmake.org cmake-commits at cmake.org
Fri Feb 9 13:44:39 EST 2007


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

Modified Files:
	cmCommandArgumentParserHelper.cxx 
	cmCommandArgumentParserHelper.h cmMakefile.cxx 
Log Message:
ENH: add atonly support to cmCommandArgumentParserHelper.cxx and remove old non-yacc parser code from cmMakefile.cxx


Index: cmCommandArgumentParserHelper.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmCommandArgumentParserHelper.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- cmCommandArgumentParserHelper.h	4 Oct 2006 18:37:41 -0000	1.9
+++ cmCommandArgumentParserHelper.h	9 Feb 2007 18:44:37 -0000	1.10
@@ -58,7 +58,7 @@
   char* CombineUnions(char* in1, char* in2);
 
   char* ExpandSpecialVariable(const char* key, const char* var);
-  char* ExpandVariable(const char* var);
+  char* ExpandVariable(const char* var, bool doingAt=false);
   char* ExpandVariableForAt(const char* var);
   void SetResult(const char* value);
 
@@ -70,7 +70,9 @@
   void SetEscapeQuotes(bool b) { this->EscapeQuotes = b; }
   void SetNoEscapeMode(bool b) { this->NoEscapeMode = b; }
   void SetReplaceAtSyntax(bool b) { this->ReplaceAtSyntax = b; }
-
+  void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; }
+  void SetAtOnly(bool b) { this->AtOnly = b; }
+  
   const char* GetError() { return this->ErrorString.c_str(); } 
   char EmptyVariable[1];
   char DCURLYVariable[3];
@@ -104,6 +106,8 @@
   std::string ErrorString;
   bool NoEscapeMode;
   bool ReplaceAtSyntax;
+  bool RemoveEmpty; 
+  bool AtOnly;
 };
 
 #endif

Index: cmCommandArgumentParserHelper.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmCommandArgumentParserHelper.cxx,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cmCommandArgumentParserHelper.cxx	4 Oct 2006 18:37:41 -0000	1.17
+++ cmCommandArgumentParserHelper.cxx	9 Feb 2007 18:44:37 -0000	1.18
@@ -27,7 +27,7 @@
 {
   this->FileLine = -1;
   this->FileName = 0;
-
+  this->RemoveEmpty = true;
   this->EmptyVariable[0] = 0;
   strcpy(this->DCURLYVariable, "${");
   strcpy(this->RCURLYVariable, "}");
@@ -38,6 +38,7 @@
 
   this->NoEscapeMode = false;
   this->ReplaceAtSyntax = false;
+  this->AtOnly = false;
 }
 
 
@@ -70,6 +71,18 @@
   if ( !key )
     {
     return this->ExpandVariable(var);
+    } 
+  if(this->AtOnly)
+    {
+    std::string ref = "$";
+    ref += key;
+    ref += "{";
+    if(var)
+      {
+      ref += var;
+      }
+    ref += "}";
+    return this->AddString(ref.c_str());
     }
   if ( strcmp(key, "ENV") == 0 )
     {
@@ -92,8 +105,21 @@
   return 0;
 }
 
-char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
+char* cmCommandArgumentParserHelper::ExpandVariable(const char* var,
+                                                    bool doingAt)
 {
+  // if we are in AtOnly mode, and we are not expanding an @ variable
+  // then put back the ${var} unexpanded
+  if(!doingAt && this->AtOnly)
+    {
+    std::string ref = "${";
+    if(var)
+      {
+      ref += var;
+      }
+    ref += "}";
+    return this->AddString(ref.c_str());
+    }
   if(!var)
     {
     return 0;
@@ -109,6 +135,10 @@
     return this->AddString(ostr.str().c_str());
     } 
   const char* value = this->Makefile->GetDefinition(var);
+  if(!value && !this->RemoveEmpty)
+    {
+    return 0;
+    }
   if (this->EscapeQuotes && value)
     {
     return this->AddString(cmSystemTools::EscapeQuotes(value).c_str());
@@ -120,15 +150,28 @@
 {
   if(this->ReplaceAtSyntax)
     {
-    return this->ExpandVariable(var);
-    }
-  else
-    {
-    std::string ref = "@";
-    ref += var;
-    ref += "@";
-    return this->AddString(ref.c_str());
+    // try to expand the variable
+    char* ret = this->ExpandVariable(var, true);
+    // if the return was 0 and we want to replace empty strings
+    // then return an empty string 
+    if(!ret && this->RemoveEmpty)
+      {
+      return this->AddString(ret);
+      }
+    // if the ret was not 0, then return it
+    if(ret)
+      {
+      return ret;
+      }
     }
+  // at this point we want to put it back because of one of these cases:
+  // - this->ReplaceAtSyntax is false  
+  // - this->ReplaceAtSyntax is true, but this->RemoveEmpty is false,
+  //   and the variable was not defined
+  std::string ref = "@";
+  ref += var;
+  ref += "@";
+  return this->AddString(ref.c_str());
 }
 
 char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2)

Index: cmMakefile.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.cxx,v
retrieving revision 1.371
retrieving revision 1.372
diff -u -d -r1.371 -r1.372
--- cmMakefile.cxx	13 Dec 2006 17:19:58 -0000	1.371
+++ cmMakefile.cxx	9 Feb 2007 18:44:37 -0000	1.372
@@ -1684,214 +1684,45 @@
   // It also supports the $ENV{VAR} syntax where VAR is looked up in
   // the current environment variables.
   
-  bool notParsed = true;
-  if ( !atOnly )
+  cmCommandArgumentParserHelper parser;
+  parser.SetMakefile(this);
+  parser.SetLineFile(line, filename);
+  parser.SetEscapeQuotes(escapeQuotes);
+  parser.SetNoEscapeMode(noEscapes);
+  parser.SetReplaceAtSyntax(replaceAt);
+  parser.SetRemoveEmpty(removeEmpty);
+  parser.SetAtOnly(atOnly);
+  int res = parser.ParseString(source.c_str(), 0);
+  if ( res )
     {
-    cmCommandArgumentParserHelper parser;
-    parser.SetMakefile(this);
-    parser.SetLineFile(line, filename);
-    parser.SetEscapeQuotes(escapeQuotes);
-    parser.SetNoEscapeMode(noEscapes);
-    parser.SetReplaceAtSyntax(replaceAt);
-    int res = parser.ParseString(source.c_str(), 0);
-    if ( res )
-      {
-      source = parser.GetResult();
-      notParsed = false;
-      }
-    else
-      {
-      cmOStringStream error;
-      error << "Syntax error in cmake code at\n"
-            << (filename?filename:"(no filename given)") 
-            << ":" << line << ":\n"
-            << parser.GetError() << ", when parsing string \"" 
-            << source.c_str() << "\"";
-      const char* versionValue
-        = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
-      int major = 0;
-      int minor = 0;
-      if ( versionValue )
-        {
-        sscanf(versionValue, "%d.%d", &major, &minor);
-        }
-      if ( major < 2 || major == 2 && minor < 1 )
-        {
-        cmSystemTools::Error(error.str().c_str());
-        cmSystemTools::SetFatalErrorOccured();
-        return source.c_str();
-        }
-      else
-        {
-        cmSystemTools::Message(error.str().c_str());
-        }
-      }
+    source = parser.GetResult();
     }
-
-  if ( notParsed )
+  else
     {
-
-    // start by look for $ or @ in the string
-    std::string::size_type markerPos;
-    if(atOnly)
-      {
-      markerPos = source.find_first_of("@");
-      }
-    else
+    cmOStringStream error;
+    error << "Syntax error in cmake code at\n"
+          << (filename?filename:"(no filename given)") 
+          << ":" << line << ":\n"
+          << parser.GetError() << ", when parsing string \"" 
+          << source.c_str() << "\"";
+    const char* versionValue
+      = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
+    int major = 0;
+    int minor = 0;
+    if ( versionValue )
       {
-      markerPos = source.find_first_of("$@");
+      sscanf(versionValue, "%d.%d", &major, &minor);
       }
-    // 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))
+    if ( major < 2 || major == 2 && minor < 1 )
       {
+      cmSystemTools::Error(error.str().c_str());
+      cmSystemTools::SetFatalErrorOccured();
       return source.c_str();
       }
-    // current position
-    std::string::size_type currentPos =0; // start at 0
-    std::string result; // string with replacements
-    // go until the the end of the string
-    while((markerPos != std::string::npos) && (markerPos < source.size()-1))
+    else
       {
-      // grab string from currentPos to the start of the variable
-      // and add it to the result
-      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(!atOnly && source[markerPos] == '$')
-        {
-        // ${var} case
-        if(source[markerPos+1] == '{')
-          {
-          endVariableMarker = '}';
-          markerStartSize = 2;
-          }
-        // $ENV{var} case
-        else if(markerPos+4 < source.size() &&
-                source[markerPos+4] == '{' &&
-                !source.substr(markerPos+1, 3).compare("ENV"))
-          {
-          endVariableMarker = '}';
-          markerStartSize = 5;
-          }
-        else
-          {
-          // bogus $ with no { so add $ to result and move on
-          result += '$'; // add bogus $ back into string
-          currentPos = markerPos+1; // move on
-          // set end var to space so we can tell bogus
-          endVariableMarker = ' '; 
-          }
-        }
-      else
-        {
-        // @VAR case
-        endVariableMarker = '@';
-        }
-      // if it was a valid variable (started with @ or ${ or $ENV{ )
-      if(endVariableMarker != ' ')
-        {
-        markerPos += markerStartSize; // move past marker
-        // find the end variable marker starting at the markerPos
-        // make sure it is a valid variable between 
-        std::string::size_type endVariablePos =
-          source.find_first_not_of(
-            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",
-            markerPos);
-        if(endVariablePos != std::string::npos && 
-          source[endVariablePos] != endVariableMarker)
-          {
-          endVariablePos = std::string::npos;
-          }
-        if(endVariablePos == std::string::npos)
-          {
-          // no end marker found so add the bogus start
-          if(endVariableMarker == '@')
-            {
-            result += '@';
-            }
-          else
-            {
-            result += (markerStartSize == 5 ? "$ENV{" : "${");
-            }
-          currentPos = markerPos;
-          }
-        else
-          {
-          // good variable remove it
-          std::string var = 
-            source.substr(markerPos, endVariablePos - markerPos);
-          bool found = false;
-          if (markerStartSize == 5) // $ENV{
-            {
-            char *ptr = getenv(var.c_str());
-            if (ptr)
-              {
-              if (escapeQuotes)
-                {
-                result += cmSystemTools::EscapeQuotes(ptr);
-                }
-              else
-                {
-                result += ptr;
-                }
-              found = true;
-              }
-            }
-          else
-            {
-            const char* lookup = this->GetDefinition(var.c_str());
-            if(lookup)
-              {
-              if (escapeQuotes)
-                {
-                result += cmSystemTools::EscapeQuotes(lookup);
-                }
-              else
-                {
-                result += lookup;
-                }
-              found = true;
-              }
-            else if(filename && (var == "CMAKE_CURRENT_LIST_FILE"))
-              {
-              result += filename;
-              found = true;
-              }
-            else if(line >= 0 && (var == "CMAKE_CURRENT_LIST_LINE"))
-              {
-              cmOStringStream ostr;
-              ostr << line;
-              result += ostr.str();
-              found = true;
-              }
-            }
-          // if found add to result, if not, then it gets blanked
-          if (!found)
-            {
-            // if no definition is found then add the var back
-            if(!removeEmpty && endVariableMarker == '@')
-              {
-              result += "@";
-              result += var;
-              result += "@";
-              }
-            }
-          // lookup var, and replace it
-          currentPos = endVariablePos+1;
-          }
-        }
-      if(atOnly)
-        {
-        markerPos = source.find_first_of("@", currentPos);
-        }
-      else
-        {
-        markerPos = source.find_first_of("$@", currentPos);
-        }
+      cmSystemTools::Message(error.str().c_str());
       }
-    result += source.substr(currentPos); // pick up the rest of the string
-    source = result;
     }
   return source.c_str();
 }



More information about the Cmake-commits mailing list