浏览代码

ENH: Use the new parser that supports nested variables

Andy Cedilnik 20 年之前
父节点
当前提交
29f7e505a5
共有 3 个文件被更改,包括 105 次插入0 次删除
  1. 52 0
      Source/CMakeLists.txt
  2. 50 0
      Source/cmMakefile.cxx
  3. 3 0
      bootstrap

+ 52 - 0
Source/CMakeLists.txt

@@ -17,6 +17,55 @@ INCLUDE_DIRECTORIES(
 # let cmake know it is supposed to use it
 # let cmake know it is supposed to use it
 ADD_DEFINITIONS(-DCMAKE_BUILD_WITH_CMAKE)
 ADD_DEFINITIONS(-DCMAKE_BUILD_WITH_CMAKE)
 
 
+OPTION(CMAKE_REGENERATE_YACCLEX
+  "Regenerate YACC and LEXX files" OFF)
+MARK_AS_ADVANCED(CMAKE_REGENERATE_YACCLEX)
+IF(CMAKE_REGENERATE_YACCLEX)
+  FIND_PROGRAM(YACC_EXECUTABLE
+    NAMES yacc bison
+    PATHS /usr/bin
+    DOC "Yacc or Bison executable")
+  FIND_PROGRAM(FLEX_EXECUTABLE
+    NAMES flex
+    PATHS /usr/bin
+    DOC "Flex executable")
+  MARK_AS_ADVANCED(YACC_EXECUTABLE FLEX_EXECUTABLE)
+  IF(YACC_EXECUTABLE)
+    SET(BISON_FLAGS)
+    IF(YACC_EXECUTABLE MATCHES "bison")
+      SET(BISON_FLAGS "--yacc")
+    ENDIF(YACC_EXECUTABLE MATCHES "bison")
+    SET(yacc_files)
+    FOREACH(name cmCommandArgument)
+      SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y")
+      SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx")
+      SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h")
+      ADD_CUSTOM_COMMAND(
+        OUTPUT "${dst}"
+        DEPENDS "${src}"
+        COMMAND ${YACC_EXECUTABLE}
+        ARGS --name-prefix=${name}_yy --defines="${hdr}" -o"${dst}" "${src}")
+      SET(yacc_files ${yacc_files} "${dst}")
+    ENDFOREACH(name)
+    ADD_CUSTOM_TARGET(RerunYacc DEPENDS ${yacc_files})
+  ENDIF(YACC_EXECUTABLE)
+  IF(FLEX_EXECUTABLE)
+    SET(lex_files)
+    FOREACH(name cmCommandArgument)
+      SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l")
+      SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx")
+      SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h")
+      ADD_CUSTOM_COMMAND(
+        OUTPUT "${dst}"
+        DEPENDS "${src}"
+        COMMAND ${FLEX_EXECUTABLE}
+        ARGS --prefix=${name}_yy --header-file="${hdr}" -o"${dst}" "${src}")
+      SET(lex_files ${lex_files} "${dst}")
+    ENDFOREACH(name)
+    ADD_CUSTOM_TARGET(RerunLex DEPENDS ${lex_files})
+  ENDIF(FLEX_EXECUTABLE)
+
+ENDIF(CMAKE_REGENERATE_YACCLEX)
 #
 #
 # Sources for CMakeLib
 # Sources for CMakeLib
 #
 #
@@ -26,6 +75,9 @@ SET(SRCS
   cmCacheManager.h
   cmCacheManager.h
   cmCommands.cxx
   cmCommands.cxx
   cmCommands.h
   cmCommands.h
+  cmCommandArgumentLexer.cxx
+  cmCommandArgumentParser.cxx
+  cmCommandArgumentParserHelper.cxx
   cmCustomCommand.cxx
   cmCustomCommand.cxx
   cmCustomCommand.h
   cmCustomCommand.h
   cmDepends.cxx
   cmDepends.cxx

+ 50 - 0
Source/cmMakefile.cxx

@@ -24,6 +24,7 @@
 #include "cmCacheManager.h"
 #include "cmCacheManager.h"
 #include "cmFunctionBlocker.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
+#include "cmCommandArgumentParserHelper.h"
 #include "cmTest.h"
 #include "cmTest.h"
 #ifdef CMAKE_BUILD_WITH_CMAKE
 #ifdef CMAKE_BUILD_WITH_CMAKE
 #  include "cmVariableWatch.h"
 #  include "cmVariableWatch.h"
@@ -1365,10 +1366,58 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
                                                 long line,
                                                 long line,
                                                 bool removeEmpty) const
                                                 bool removeEmpty) const
 {
 {
+  if ( source.empty() || source.find_first_of("$@") == source.npos)
+    {
+    return source.c_str();
+    }
   // This method replaces ${VAR} and @VAR@ where VAR is looked up
   // This method replaces ${VAR} and @VAR@ where VAR is looked up
   // with GetDefinition(), if not found in the map, nothing is expanded.
   // with GetDefinition(), if not found in the map, nothing is expanded.
   // It also supports the $ENV{VAR} syntax where VAR is looked up in
   // It also supports the $ENV{VAR} syntax where VAR is looked up in
   // the current environment variables.
   // the current environment variables.
+  
+  bool notParsed = true;
+  if ( !atOnly )
+    {
+    cmCommandArgumentParserHelper parser;
+    parser.SetMakefile(this);
+    parser.SetLineFile(line, filename);
+    parser.SetEscapeQuotes(escapeQuotes);
+    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 << ":" << 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());
+        }
+      //std::cerr << "[" << source.c_str() << "] results in: [" << parser.GetResult() << "]" << std::endl;
+      }
+    }
+
+  if ( notParsed )
+    {
 
 
   // start by look for $ or @ in the string
   // start by look for $ or @ in the string
   std::string::size_type markerPos;
   std::string::size_type markerPos;
@@ -1521,6 +1570,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
     }
     }
   result += source.substr(currentPos); // pick up the rest of the string
   result += source.substr(currentPos); // pick up the rest of the string
   source = result;
   source = result;
+      }
   return source.c_str();
   return source.c_str();
 }
 }
 
 

+ 3 - 0
bootstrap

@@ -36,6 +36,9 @@ CMAKE_CXX_SOURCES="\
   cmake  \
   cmake  \
   cmakewizard  \
   cmakewizard  \
   cmakemain \
   cmakemain \
+  cmCommandArgumentLexer \
+  cmCommandArgumentParser \
+  cmCommandArgumentParserHelper \
   cmDepends \
   cmDepends \
   cmDependsC \
   cmDependsC \
   cmMakeDepend \
   cmMakeDepend \