Browse Source

Merge topic 'cmake-syntax'

b93982f Merge branch 'dev/fix-variable-watch-crash' into cmake-syntax
c50f7ed cmListFileLexer: Modify flex output to avoid Borland warning
bf73264 Warn about unquoted arguments that look like long brackets
58e5241 Warn about arguments not separated by whitespace
e75b69f cmListFileCache: Convert CMake language parser to class
e945949 Add RunCMake.Syntax test cases for command invocation styles
0546484 cmListFileArgument: Generalize 'Quoted' bool to 'Delimeter' enum
28685ad cmListFileLexer: Split normal and legacy unquoted arguments
1eafa3e cmListFileLexer: Fix line number after backslash in string
f3155cd Add RunCMake.Syntax test to cover argument parsing
Brad King 12 years ago
parent
commit
81aaad0c73
50 changed files with 651 additions and 247 deletions
  1. 3 2
      Source/cmCPluginAPI.cxx
  2. 150 72
      Source/cmListFileCache.cxx
  3. 11 6
      Source/cmListFileCache.h
  4. 256 155
      Source/cmListFileLexer.c
  5. 1 0
      Source/cmListFileLexer.h
  6. 23 3
      Source/cmListFileLexer.in.l
  7. 1 1
      Source/cmMacroCommand.cxx
  8. 1 1
      Source/cmMakefile.cxx
  9. 10 5
      Source/cmVariableWatchCommand.cxx
  10. 2 2
      Source/cmWhileCommand.cxx
  11. 1 0
      Tests/RunCMake/CMakeLists.txt
  12. 1 0
      Tests/RunCMake/Syntax/.gitattributes
  13. 35 0
      Tests/RunCMake/Syntax/BracketWarn-stderr.txt
  14. 1 0
      Tests/RunCMake/Syntax/BracketWarn-stdout.txt
  15. 1 0
      Tests/RunCMake/Syntax/BracketWarn.cmake
  16. 3 0
      Tests/RunCMake/Syntax/CMakeLists.txt
  17. 4 0
      Tests/RunCMake/Syntax/CommandComments-stderr.txt
  18. 6 0
      Tests/RunCMake/Syntax/CommandComments.cmake
  19. 1 0
      Tests/RunCMake/Syntax/CommandError0-result.txt
  20. 8 0
      Tests/RunCMake/Syntax/CommandError0-stderr.txt
  21. 2 0
      Tests/RunCMake/Syntax/CommandError0.cmake
  22. 1 0
      Tests/RunCMake/Syntax/CommandError1-result.txt
  23. 7 0
      Tests/RunCMake/Syntax/CommandError1-stderr.txt
  24. 1 0
      Tests/RunCMake/Syntax/CommandError1.cmake
  25. 3 0
      Tests/RunCMake/Syntax/CommandNewlines-stderr.txt
  26. 10 0
      Tests/RunCMake/Syntax/CommandNewlines.cmake
  27. 6 0
      Tests/RunCMake/Syntax/CommandSpaces-stderr.txt
  28. 6 0
      Tests/RunCMake/Syntax/CommandSpaces.cmake
  29. 6 0
      Tests/RunCMake/Syntax/CommandTabs-stderr.txt
  30. 6 0
      Tests/RunCMake/Syntax/CommandTabs.cmake
  31. 17 0
      Tests/RunCMake/Syntax/RunCMakeTest.cmake
  32. 1 0
      Tests/RunCMake/Syntax/String0-stderr.txt
  33. 2 0
      Tests/RunCMake/Syntax/String0.cmake
  34. 3 0
      Tests/RunCMake/Syntax/String1-stderr.txt
  35. 3 0
      Tests/RunCMake/Syntax/String1.cmake
  36. 19 0
      Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
  37. 4 0
      Tests/RunCMake/Syntax/StringNoSpace.cmake
  38. 1 0
      Tests/RunCMake/Syntax/Unquoted0-stderr.txt
  39. 2 0
      Tests/RunCMake/Syntax/Unquoted0.cmake
  40. 1 0
      Tests/RunCMake/Syntax/Unquoted1-stderr.txt
  41. 1 0
      Tests/RunCMake/Syntax/Unquoted1.cmake
  42. 1 0
      Tests/RunCMake/Syntax/UnterminatedCall1-result.txt
  43. 7 0
      Tests/RunCMake/Syntax/UnterminatedCall1-stderr.txt
  44. 1 0
      Tests/RunCMake/Syntax/UnterminatedCall1.cmake
  45. 1 0
      Tests/RunCMake/Syntax/UnterminatedCall2-result.txt
  46. 7 0
      Tests/RunCMake/Syntax/UnterminatedCall2-stderr.txt
  47. 3 0
      Tests/RunCMake/Syntax/UnterminatedCall2.cmake
  48. 1 0
      Tests/RunCMake/Syntax/UnterminatedString-result.txt
  49. 8 0
      Tests/RunCMake/Syntax/UnterminatedString-stderr.txt
  50. 1 0
      Tests/RunCMake/Syntax/UnterminatedString.cmake

+ 3 - 2
Source/cmCPluginAPI.cxx

@@ -422,8 +422,9 @@ int CCONV cmExecuteCommand(void *arg, const char *name,
   for(int i = 0; i < numArgs; ++i)
     {
     // Assume all arguments are quoted.
-    lff.Arguments.push_back(cmListFileArgument(args[i], true,
-                                               "[CMake-Plugin]", 0));
+    lff.Arguments.push_back(
+      cmListFileArgument(args[i], cmListFileArgument::Quoted,
+                         "[CMake-Plugin]", 0));
     }
   cmExecutionStatus status;
   return mf->ExecuteCommand(lff,status);

+ 150 - 72
Source/cmListFileCache.cxx

@@ -22,45 +22,58 @@
 # pragma warn -8060 /* possibly incorrect assignment */
 #endif
 
-bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
-                                  cmListFileFunction& function,
-                                  const char* filename);
+//----------------------------------------------------------------------------
+struct cmListFileParser
+{
+  cmListFileParser(cmListFile* lf, cmMakefile* mf, const char* filename);
+  ~cmListFileParser();
+  bool ParseFile();
+  bool ParseFunction(const char* name, long line);
+  void AddArgument(cmListFileLexer_Token* token,
+                   cmListFileArgument::Delimiter delim);
+  cmListFile* ListFile;
+  cmMakefile* Makefile;
+  const char* FileName;
+  cmListFileLexer* Lexer;
+  cmListFileFunction Function;
+  enum { SeparationOkay, SeparationWarning } Separation;
+};
 
-bool cmListFile::ParseFile(const char* filename,
-                           bool topLevel,
-                           cmMakefile *mf)
+//----------------------------------------------------------------------------
+cmListFileParser::cmListFileParser(cmListFile* lf, cmMakefile* mf,
+                                   const char* filename):
+  ListFile(lf), Makefile(mf), FileName(filename),
+  Lexer(cmListFileLexer_New())
 {
-  if(!cmSystemTools::FileExists(filename))
-    {
-    return false;
-    }
+}
 
-  // Create the scanner.
-  cmListFileLexer* lexer = cmListFileLexer_New();
-  if(!lexer)
-    {
-    cmSystemTools::Error("cmListFileCache: error allocating lexer ");
-    return false;
-    }
+//----------------------------------------------------------------------------
+cmListFileParser::~cmListFileParser()
+{
+  cmListFileLexer_Delete(this->Lexer);
+}
 
+//----------------------------------------------------------------------------
+bool cmListFileParser::ParseFile()
+{
   // Open the file.
-  if(!cmListFileLexer_SetFileName(lexer, filename))
+  if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName))
     {
-    cmListFileLexer_Delete(lexer);
     cmSystemTools::Error("cmListFileCache: error can not open file ",
-                         filename);
+                         this->FileName);
     return false;
     }
 
   // Use a simple recursive-descent parser to process the token
   // stream.
-  this->ModifiedTime = cmSystemTools::ModifiedTime(filename);
-  bool parseError = false;
   bool haveNewline = true;
-  cmListFileLexer_Token* token;
-  while(!parseError && (token = cmListFileLexer_Scan(lexer)))
+  while(cmListFileLexer_Token* token =
+        cmListFileLexer_Scan(this->Lexer))
     {
-    if(token->type == cmListFileLexer_Token_Newline)
+    if(token->type == cmListFileLexer_Token_Space)
+      {
+      }
+    else if(token->type == cmListFileLexer_Token_Newline)
       {
       haveNewline = true;
       }
@@ -69,51 +82,66 @@ bool cmListFile::ParseFile(const char* filename,
       if(haveNewline)
         {
         haveNewline = false;
-        cmListFileFunction inFunction;
-        inFunction.Name = token->text;
-        inFunction.FilePath = filename;
-        inFunction.Line = token->line;
-        if(cmListFileCacheParseFunction(lexer, inFunction, filename))
+        if(this->ParseFunction(token->text, token->line))
           {
-          this->Functions.push_back(inFunction);
+          this->ListFile->Functions.push_back(this->Function);
           }
         else
           {
-          parseError = true;
+          return false;
           }
         }
       else
         {
         cmOStringStream error;
         error << "Error in cmake code at\n"
-              << filename << ":" << token->line << ":\n"
+              << this->FileName << ":" << token->line << ":\n"
               << "Parse error.  Expected a newline, got "
-              << cmListFileLexer_GetTypeAsString(lexer, token->type)
+              << cmListFileLexer_GetTypeAsString(this->Lexer, token->type)
               << " with text \"" << token->text << "\".";
         cmSystemTools::Error(error.str().c_str());
-        parseError = true;
+        return false;
         }
       }
     else
       {
       cmOStringStream error;
       error << "Error in cmake code at\n"
-            << filename << ":" << token->line << ":\n"
+            << this->FileName << ":" << token->line << ":\n"
             << "Parse error.  Expected a command name, got "
-            << cmListFileLexer_GetTypeAsString(lexer, token->type)
+            << cmListFileLexer_GetTypeAsString(this->Lexer, token->type)
             << " with text \""
             << token->text << "\".";
       cmSystemTools::Error(error.str().c_str());
-      parseError = true;
+      return false;
       }
     }
-  if (parseError)
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListFile::ParseFile(const char* filename,
+                           bool topLevel,
+                           cmMakefile *mf)
+{
+  if(!cmSystemTools::FileExists(filename))
+    {
+    return false;
+    }
+
+  bool parseError = false;
+  this->ModifiedTime = cmSystemTools::ModifiedTime(filename);
+
+  {
+  cmListFileParser parser(this, mf, filename);
+  parseError = !parser.ParseFile();
+  }
+
+  if(parseError)
     {
     this->ModifiedTime = 0;
     }
 
-  cmListFileLexer_Delete(lexer);
-
   // do we need a cmake_policy(VERSION call?
   if(topLevel)
   {
@@ -196,7 +224,8 @@ bool cmListFile::ParseFile(const char* filename,
       {
       cmListFileFunction project;
       project.Name = "PROJECT";
-      cmListFileArgument prj("Project", false, filename, 0);
+      cmListFileArgument prj("Project", cmListFileArgument::Unquoted,
+                             filename, 0);
       project.Arguments.push_back(prj);
       this->Functions.insert(this->Functions.begin(),project);
       }
@@ -208,17 +237,24 @@ bool cmListFile::ParseFile(const char* filename,
   return true;
 }
 
-bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
-                                  cmListFileFunction& function,
-                                  const char* filename)
+//----------------------------------------------------------------------------
+bool cmListFileParser::ParseFunction(const char* name, long line)
 {
+  // Inintialize a new function call.
+  this->Function = cmListFileFunction();
+  this->Function.FilePath = this->FileName;
+  this->Function.Name = name;
+  this->Function.Line = line;
+
   // Command name has already been parsed.  Read the left paren.
   cmListFileLexer_Token* token;
-  if(!(token = cmListFileLexer_Scan(lexer)))
+  while((token = cmListFileLexer_Scan(this->Lexer)) &&
+        token->type == cmListFileLexer_Token_Space) {}
+  if(!token)
     {
     cmOStringStream error;
-    error << "Error in cmake code at\n"
-          << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n"
+    error << "Error in cmake code at\n" << this->FileName << ":"
+          << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
           << "Parse error.  Function missing opening \"(\".";
     cmSystemTools::Error(error.str().c_str());
     return false;
@@ -226,26 +262,33 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
   if(token->type != cmListFileLexer_Token_ParenLeft)
     {
     cmOStringStream error;
-    error << "Error in cmake code at\n"
-          << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n"
+    error << "Error in cmake code at\n" << this->FileName << ":"
+          << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
           << "Parse error.  Expected \"(\", got "
-          << cmListFileLexer_GetTypeAsString(lexer, token->type)
+          << cmListFileLexer_GetTypeAsString(this->Lexer, token->type)
           << " with text \"" << token->text << "\".";
     cmSystemTools::Error(error.str().c_str());
     return false;
     }
 
   // Arguments.
-  unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
+  unsigned long lastLine;
   unsigned long parenDepth = 0;
-  while((token = cmListFileLexer_Scan(lexer)))
+  this->Separation = SeparationOkay;
+  while((lastLine = cmListFileLexer_GetCurrentLine(this->Lexer),
+         token = cmListFileLexer_Scan(this->Lexer)))
     {
+    if(token->type == cmListFileLexer_Token_Space ||
+       token->type == cmListFileLexer_Token_Newline)
+      {
+      this->Separation = SeparationOkay;
+      continue;
+      }
     if(token->type == cmListFileLexer_Token_ParenLeft)
       {
       parenDepth++;
-      cmListFileArgument a("(",
-                           false, filename, token->line);
-      function.Arguments.push_back(a);
+      this->AddArgument(token, cmListFileArgument::Unquoted);
+      this->Separation = SeparationOkay;
       }
     else if(token->type == cmListFileLexer_Token_ParenRight)
       {
@@ -254,43 +297,39 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
         return true;
         }
       parenDepth--;
-      cmListFileArgument a(")",
-                           false, filename, token->line);
-      function.Arguments.push_back(a);
+      this->Separation = SeparationOkay;
+      this->AddArgument(token, cmListFileArgument::Unquoted);
+      this->Separation = SeparationWarning;
       }
     else if(token->type == cmListFileLexer_Token_Identifier ||
             token->type == cmListFileLexer_Token_ArgumentUnquoted)
       {
-      cmListFileArgument a(token->text,
-                           false, filename, token->line);
-      function.Arguments.push_back(a);
+      this->AddArgument(token, cmListFileArgument::Unquoted);
+      this->Separation = SeparationWarning;
       }
     else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
       {
-      cmListFileArgument a(token->text,
-                           true, filename, token->line);
-      function.Arguments.push_back(a);
+      this->AddArgument(token, cmListFileArgument::Quoted);
+      this->Separation = SeparationWarning;
       }
-    else if(token->type != cmListFileLexer_Token_Newline)
+    else
       {
       // Error.
       cmOStringStream error;
-      error << "Error in cmake code at\n"
-            << filename << ":" << cmListFileLexer_GetCurrentLine(lexer)
-            << ":\n"
+      error << "Error in cmake code at\n" << this->FileName << ":"
+            << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
             << "Parse error.  Function missing ending \")\".  "
             << "Instead found "
-            << cmListFileLexer_GetTypeAsString(lexer, token->type)
+            << cmListFileLexer_GetTypeAsString(this->Lexer, token->type)
             << " with text \"" << token->text << "\".";
       cmSystemTools::Error(error.str().c_str());
       return false;
       }
-    lastLine = cmListFileLexer_GetCurrentLine(lexer);
     }
 
   cmOStringStream error;
   error << "Error in cmake code at\n"
-        << filename << ":" << lastLine << ":\n"
+        << this->FileName << ":" << lastLine << ":\n"
         << "Parse error.  Function missing ending \")\".  "
         << "End of file reached.";
   cmSystemTools::Error(error.str().c_str());
@@ -298,6 +337,45 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
   return false;
 }
 
+//----------------------------------------------------------------------------
+void cmListFileParser::AddArgument(cmListFileLexer_Token* token,
+                                   cmListFileArgument::Delimiter delim)
+{
+  cmListFileArgument a(token->text, delim, this->FileName, token->line);
+  this->Function.Arguments.push_back(a);
+  if(delim == cmListFileArgument::Unquoted)
+    {
+    // Warn about a future behavior change.
+    const char* c = a.Value.c_str();
+    if(*c++ == '[')
+      {
+      while(*c == '=')
+        { ++c; }
+      if(*c == '[')
+        {
+        cmOStringStream m;
+        m << "Syntax Warning in cmake code at\n"
+          << "  " << this->FileName << ":" << token->line << ":"
+          << token->column << "\n"
+          << "A future version of CMake may treat unquoted argument:\n"
+          << "  " << a.Value << "\n"
+          << "as an opening long bracket.  Double-quote the argument.";
+        this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
+        }
+      }
+    }
+  if(this->Separation == SeparationOkay)
+    {
+    return;
+    }
+  cmOStringStream m;
+  m << "Syntax Warning in cmake code at\n"
+    << "  " << this->FileName << ":" << token->line << ":"
+    << token->column << "\n"
+    << "Argument not separated from preceding token by whitespace.";
+  this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
+}
+
 //----------------------------------------------------------------------------
 std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
 {

+ 11 - 6
Source/cmListFileCache.h

@@ -25,22 +25,27 @@ class cmMakefile;
 
 struct cmListFileArgument
 {
-  cmListFileArgument(): Value(), Quoted(false), FilePath(0), Line(0) {}
+  enum Delimiter
+    {
+    Unquoted,
+    Quoted
+    };
+  cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {}
   cmListFileArgument(const cmListFileArgument& r):
-    Value(r.Value), Quoted(r.Quoted), FilePath(r.FilePath), Line(r.Line) {}
-  cmListFileArgument(const std::string& v, bool q, const char* file,
-                     long line): Value(v), Quoted(q),
+    Value(r.Value), Delim(r.Delim), FilePath(r.FilePath), Line(r.Line) {}
+  cmListFileArgument(const std::string& v, Delimiter d, const char* file,
+                     long line): Value(v), Delim(d),
                                  FilePath(file), Line(line) {}
   bool operator == (const cmListFileArgument& r) const
     {
-    return (this->Value == r.Value) && (this->Quoted == r.Quoted);
+    return (this->Value == r.Value) && (this->Delim == r.Delim);
     }
   bool operator != (const cmListFileArgument& r) const
     {
     return !(*this == r);
     }
   std::string Value;
-  bool Quoted;
+  Delimiter Delim;
   const char* FilePath;
   long Line;
 };

+ 256 - 155
Source/cmListFileLexer.c

@@ -9,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
+#define YY_FLEX_SUBMINOR_VERSION 35
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -31,7 +31,15 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
@@ -46,7 +54,6 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t;
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -77,6 +84,8 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -86,11 +95,12 @@ typedef unsigned int flex_uint32_t;
 
 #else   /* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif  /* __STDC__ */
+#endif  /* defined (__STDC__) */
 #endif  /* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -126,8 +136,6 @@ typedef void* yyscan_t;
 #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
 #define yy_flex_debug yyg->yy_flex_debug_r
 
-int cmListFileLexer_yylex_init (yyscan_t* scanner);
-
 /* Enter a start condition.  This macro really ought to take a parameter,
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
@@ -151,9 +159,21 @@ int cmListFileLexer_yylex_init (yyscan_t* scanner);
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
 #define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
 #endif
 
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
 #define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
@@ -192,14 +212,9 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
                 } \
         while ( 0 )
 
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
 #endif
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -354,8 +369,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
         *yy_cp = '\0'; \
         yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 14
-#define YY_END_OF_BUFFER 15
+#define YY_NUM_RULES 16
+#define YY_END_OF_BUFFER 17
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -363,12 +378,13 @@ struct yy_trans_info
         flex_int32_t yy_verify;
         flex_int32_t yy_nxt;
         };
-static yyconst flex_int16_t yy_accept[39] =
+static yyconst flex_int16_t yy_accept[45] =
     {   0,
-        0,    0,    0,    0,   15,    6,   12,    1,    7,    2,
-        6,    3,    4,    6,   13,    8,    9,   10,   11,    6,
-        0,    6,    0,    2,    0,    5,    6,    8,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0
+        0,    0,    0,    0,   17,    6,   14,    1,    8,    2,
+        6,    3,    4,    6,   15,    9,   11,   12,   13,    6,
+        0,    6,    0,   14,    2,    0,    5,    6,    9,    0,
+       10,    0,    7,    0,    0,    0,    7,    0,    7,    0,
+        0,    0,    0,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -405,64 +421,70 @@ static yyconst flex_int32_t yy_ec[256] =
 
 static yyconst flex_int32_t yy_meta[13] =
     {   0,
-        1,    1,    2,    1,    3,    1,    1,    1,    4,    4,
-        4,    1
+        1,    2,    3,    2,    4,    1,    1,    1,    5,    5,
+        5,    1
     } ;
 
-static yyconst flex_int16_t yy_base[48] =
+static yyconst flex_int16_t yy_base[56] =
     {   0,
-        0,    0,   10,   20,   34,   32,   89,   89,   89,    0,
-       23,   89,   89,   35,    0,   18,   89,   89,   44,    0,
-       49,   21,    0,    0,   19,    0,    0,   15,   59,    0,
-       18,    0,   15,   12,   11,   10,    9,   89,   64,   68,
-       72,   76,   80,   13,   84,   12,   10
+        0,    0,   10,   20,   38,   32,    0,  109,  109,    0,
+       28,  109,  109,   35,    0,   23,  109,  109,   44,    0,
+       49,   26,    0,    0,    0,   22,    0,    0,   18,   24,
+      109,    0,   61,   20,    0,   18,    0,   17,   16,    0,
+       12,   11,   10,  109,   73,   16,   78,   83,   88,   93,
+       12,   98,   11,  103,    9
     } ;
 
-static yyconst flex_int16_t yy_def[48] =
+static yyconst flex_int16_t yy_def[56] =
     {   0,
-       38,    1,   39,   39,   38,   38,   38,   38,   38,   40,
-        6,   38,   38,    6,   41,   42,   38,   38,   42,    6,
-       38,    6,   43,   40,   44,   14,    6,   42,   42,   21,
-       21,   45,   46,   44,   47,   46,   47,    0,   38,   38,
-       38,   38,   38,   38,   38,   38,   38
+       44,    1,   45,   45,   44,   44,   46,   44,   44,   47,
+        6,   44,   44,    6,   48,   49,   44,   44,   49,    6,
+       44,    6,   50,   46,   47,   51,   14,    6,   49,   49,
+       44,   21,   44,   21,   52,   53,   33,   51,   33,   54,
+       55,   53,   55,    0,   44,   44,   44,   44,   44,   44,
+       44,   44,   44,   44,   44
     } ;
 
-static yyconst flex_int16_t yy_nxt[102] =
+static yyconst flex_int16_t yy_nxt[122] =
     {   0,
         6,    7,    8,    7,    9,   10,   11,   12,   13,    6,
-       14,   15,   17,   37,   18,   36,   34,   30,   20,   30,
-       27,   19,   17,   20,   18,   35,   29,   27,   33,   29,
-       25,   19,   20,   38,   38,   38,   21,   38,   22,   38,
-       38,   20,   20,   23,   26,   26,   28,   38,   28,   30,
-       30,   38,   38,   20,   38,   31,   38,   38,   30,   30,
-       32,   28,   38,   28,   16,   16,   16,   16,   24,   38,
-       24,   24,   27,   38,   27,   27,   28,   38,   38,   28,
-       20,   38,   20,   20,   30,   38,   30,   30,    5,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-
-       38
+       14,   15,   17,   43,   18,   42,   38,   24,   32,   33,
+       32,   19,   17,   36,   18,   37,   33,   41,   29,   30,
+       37,   19,   20,   36,   30,   26,   21,   44,   22,   44,
+       44,   20,   20,   23,   27,   27,   31,   44,   29,   32,
+       32,   44,   44,   33,   44,   34,   44,   44,   32,   32,
+       35,   33,   44,   44,   44,   21,   44,   39,   44,   44,
+       33,   33,   40,   16,   16,   16,   16,   16,   25,   25,
+       44,   25,   25,   28,   28,   44,   28,   28,   29,   29,
+       44,   44,   29,   20,   20,   44,   20,   20,   32,   32,
+
+       44,   32,   32,   33,   33,   44,   33,   33,    5,   44,
+       44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
+       44
     } ;
 
-static yyconst flex_int16_t yy_chk[102] =
+static yyconst flex_int16_t yy_chk[122] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    3,   47,    3,   46,   44,   37,   36,   35,
-       34,    3,    4,   33,    4,   31,   28,   25,   22,   16,
-       11,    4,    6,    5,    0,    0,    6,    0,    6,    0,
+        1,    1,    3,   55,    3,   53,   51,   46,   43,   42,
+       41,    3,    4,   39,    4,   38,   36,   34,   30,   29,
+       26,    4,    6,   22,   16,   11,    6,    5,    6,    0,
         0,    6,    6,    6,   14,   14,   19,    0,   19,   21,
        21,    0,    0,   21,    0,   21,    0,    0,   21,   21,
-       21,   29,    0,   29,   39,   39,   39,   39,   40,    0,
-       40,   40,   41,    0,   41,   41,   42,    0,    0,   42,
-       43,    0,   43,   43,   45,    0,   45,   45,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-
-       38
+       21,   33,    0,    0,    0,   33,    0,   33,    0,    0,
+       33,   33,   33,   45,   45,   45,   45,   45,   47,   47,
+        0,   47,   47,   48,   48,    0,   48,   48,   49,   49,
+        0,    0,   49,   50,   50,    0,   50,   50,   52,   52,
+
+        0,   52,   52,   54,   54,    0,   54,   54,   44,   44,
+       44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
+       44
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[15] =
+static yyconst flex_int32_t yy_rule_can_match_eol[17] =
     {   0,
-1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,     };
+1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -494,9 +516,11 @@ Run flex like this:
 
 Modify cmListFileLexer.c:
   - remove TABs
+  - remove use of the 'register' storage class specifier
   - remove the yyunput function
   - add a statement "(void)yyscanner;" to the top of these methods:
       yy_fatal_error, cmListFileLexer_yyalloc, cmListFileLexer_yyrealloc, cmListFileLexer_yyfree
+  - remove statement "yyscanner = NULL;" from cmListFileLexer_yylex_destroy
   - remove all YY_BREAK lines occurring right after return statements
   - remove the isatty forward declaration
 
@@ -540,7 +564,7 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
 
 /*--------------------------------------------------------------------------*/
 
-#line 568 "cmListFileLexer.c"
+#line 570 "cmListFileLexer.c"
 
 #define INITIAL 0
 #define STRING 1
@@ -591,6 +615,12 @@ struct yyguts_t
 
     }; /* end struct yyguts_t */
 
+static int yy_init_globals (yyscan_t yyscanner );
+
+int cmListFileLexer_yylex_init (yyscan_t* scanner);
+
+int cmListFileLexer_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
@@ -620,6 +650,10 @@ int cmListFileLexer_yyget_lineno (yyscan_t yyscanner );
 
 void cmListFileLexer_yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int cmListFileLexer_yyget_column  (yyscan_t yyscanner );
+
+void cmListFileLexer_yyset_column (int column_no ,yyscan_t yyscanner );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -652,7 +686,12 @@ static int input (yyscan_t yyscanner );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
 #define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -660,7 +699,7 @@ static int input (yyscan_t yyscanner );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -754,14 +793,14 @@ YY_DECL
         int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 100 "cmListFileLexer.in.l"
+#line 82 "cmListFileLexer.in.l"
 
 
-#line 787 "cmListFileLexer.c"
+#line 804 "cmListFileLexer.c"
 
-        if ( yyg->yy_init )
+        if ( !yyg->yy_init )
                 {
-                yyg->yy_init = 0;
+                yyg->yy_init = 1;
 
 #ifdef YY_USER_INIT
                 YY_USER_INIT;
@@ -810,13 +849,13 @@ yy_match:
                         while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                 {
                                 yy_current_state = (int) yy_def[yy_current_state];
-                                if ( yy_current_state >= 39 )
+                                if ( yy_current_state >= 45 )
                                         yy_c = yy_meta[(unsigned int) yy_c];
                                 }
                         yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                         ++yy_cp;
                         }
-                while ( yy_base[yy_current_state] != 89 );
+                while ( yy_base[yy_current_state] != 109 );
 
 yy_find_action:
                 yy_act = yy_accept[yy_current_state];
@@ -855,7 +894,7 @@ do_action:      /* This label is used only to access EOF actions. */
 case 1:
 /* rule 1 can match eol */
 YY_RULE_SETUP
-#line 102 "cmListFileLexer.in.l"
+#line 84 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_Newline;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -865,14 +904,14 @@ YY_RULE_SETUP
 }
 case 2:
 YY_RULE_SETUP
-#line 110 "cmListFileLexer.in.l"
+#line 92 "cmListFileLexer.in.l"
 {
   lexer->column += yyleng;
 }
         YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 114 "cmListFileLexer.in.l"
+#line 96 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_ParenLeft;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -881,7 +920,7 @@ YY_RULE_SETUP
 }
 case 4:
 YY_RULE_SETUP
-#line 121 "cmListFileLexer.in.l"
+#line 103 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_ParenRight;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -890,7 +929,7 @@ YY_RULE_SETUP
 }
 case 5:
 YY_RULE_SETUP
-#line 128 "cmListFileLexer.in.l"
+#line 110 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_Identifier;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -899,7 +938,7 @@ YY_RULE_SETUP
 }
 case 6:
 YY_RULE_SETUP
-#line 135 "cmListFileLexer.in.l"
+#line 117 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -908,7 +947,16 @@ YY_RULE_SETUP
 }
 case 7:
 YY_RULE_SETUP
-#line 142 "cmListFileLexer.in.l"
+#line 124 "cmListFileLexer.in.l"
+{
+  lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  cmListFileLexerSetToken(lexer, yytext, yyleng);
+  lexer->column += yyleng;
+  return 1;
+}
+case 8:
+YY_RULE_SETUP
+#line 131 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
   cmListFileLexerSetToken(lexer, "", 0);
@@ -916,58 +964,69 @@ YY_RULE_SETUP
   BEGIN(STRING);
 }
         YY_BREAK
-case 8:
-/* rule 8 can match eol */
+case 9:
 YY_RULE_SETUP
-#line 149 "cmListFileLexer.in.l"
+#line 138 "cmListFileLexer.in.l"
 {
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
         YY_BREAK
-case 9:
-/* rule 9 can match eol */
+case 10:
+/* rule 10 can match eol */
 YY_RULE_SETUP
-#line 154 "cmListFileLexer.in.l"
+#line 143 "cmListFileLexer.in.l"
 {
   cmListFileLexerAppend(lexer, yytext, yyleng);
   ++lexer->line;
   lexer->column = 1;
 }
         YY_BREAK
-case 10:
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 149 "cmListFileLexer.in.l"
+{
+  cmListFileLexerAppend(lexer, yytext, yyleng);
+  ++lexer->line;
+  lexer->column = 1;
+}
+        YY_BREAK
+case 12:
 YY_RULE_SETUP
-#line 160 "cmListFileLexer.in.l"
+#line 155 "cmListFileLexer.in.l"
 {
   lexer->column += yyleng;
   BEGIN(INITIAL);
   return 1;
 }
-case 11:
+case 13:
 YY_RULE_SETUP
-#line 166 "cmListFileLexer.in.l"
+#line 161 "cmListFileLexer.in.l"
 {
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
         YY_BREAK
 case YY_STATE_EOF(STRING):
-#line 171 "cmListFileLexer.in.l"
+#line 166 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_BadString;
   BEGIN(INITIAL);
   return 1;
 }
-case 12:
+case 14:
 YY_RULE_SETUP
-#line 177 "cmListFileLexer.in.l"
+#line 172 "cmListFileLexer.in.l"
 {
+  lexer->token.type = cmListFileLexer_Token_Space;
+  cmListFileLexerSetToken(lexer, yytext, yyleng);
   lexer->column += yyleng;
+  return 1;
 }
-        YY_BREAK
-case 13:
+case 15:
 YY_RULE_SETUP
-#line 181 "cmListFileLexer.in.l"
+#line 179 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_BadCharacter;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -975,18 +1034,18 @@ YY_RULE_SETUP
   return 1;
 }
 case YY_STATE_EOF(INITIAL):
-#line 188 "cmListFileLexer.in.l"
+#line 186 "cmListFileLexer.in.l"
 {
   lexer->token.type = cmListFileLexer_Token_None;
   cmListFileLexerSetToken(lexer, 0, 0);
   return 0;
 }
-case 14:
+case 16:
 YY_RULE_SETUP
-#line 194 "cmListFileLexer.in.l"
+#line 192 "cmListFileLexer.in.l"
 ECHO;
         YY_BREAK
-#line 1025 "cmListFileLexer.c"
+#line 1064 "cmListFileLexer.c"
 
         case YY_END_OF_BUFFER:
                 {
@@ -1171,7 +1230,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
         else
                 {
-                        size_t num_to_read =
+                        int num_to_read =
                         YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
                 while ( num_to_read <= 0 )
@@ -1216,7 +1275,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
                 /* Read in more data. */
                 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                        yyg->yy_n_chars, num_to_read );
+                        yyg->yy_n_chars, (size_t) num_to_read );
 
                 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
                 }
@@ -1240,6 +1299,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
         else
                 ret_val = EOB_ACT_CONTINUE_SCAN;
 
+        if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+                /* Extend the array by 50%, plus the number we really need. */
+                yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+                YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmListFileLexer_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+                if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                        YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+        }
+
         yyg->yy_n_chars += number_to_move;
         YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
         YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1270,7 +1337,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
                 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                         {
                         yy_current_state = (int) yy_def[yy_current_state];
-                        if ( yy_current_state >= 39 )
+                        if ( yy_current_state >= 45 )
                                 yy_c = yy_meta[(unsigned int) yy_c];
                         }
                 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1287,7 +1354,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
     static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
 {
         int yy_is_jam;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
         char *yy_cp = yyg->yy_c_buf_p;
 
         YY_CHAR yy_c = 1;
@@ -1299,11 +1366,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
         while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                 {
                 yy_current_state = (int) yy_def[yy_current_state];
-                if ( yy_current_state >= 39 )
+                if ( yy_current_state >= 45 )
                         yy_c = yy_meta[(unsigned int) yy_c];
                 }
         yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-        yy_is_jam = (yy_current_state == 38);
+        yy_is_jam = (yy_current_state == 44);
 
         return yy_is_jam ? 0 : yy_current_state;
 }
@@ -1633,6 +1700,8 @@ static void cmListFileLexer_yyensure_buffer_stack (yyscan_t yyscanner)
                 yyg->yy_buffer_stack = (struct yy_buffer_state**)cmListFileLexer_yyalloc
                                                                 (num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                 , yyscanner);
+                if ( ! yyg->yy_buffer_stack )
+                        YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yyensure_buffer_stack()" );
 
                 memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 
@@ -1651,6 +1720,8 @@ static void cmListFileLexer_yyensure_buffer_stack (yyscan_t yyscanner)
                                                                 (yyg->yy_buffer_stack,
                                                                 num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                 , yyscanner);
+                if ( ! yyg->yy_buffer_stack )
+                        YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yyensure_buffer_stack()" );
 
                 /* zero only the new slots.*/
                 memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1695,26 +1766,26 @@ YY_BUFFER_STATE cmListFileLexer_yy_scan_buffer  (char * base, yy_size_t  size ,
 
 /** Setup the input buffer state to scan a string. The next call to cmListFileLexer_yylex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
  *       cmListFileLexer_yy_scan_bytes() instead.
  */
-YY_BUFFER_STATE cmListFileLexer_yy_scan_string (yyconst char * yy_str , yyscan_t yyscanner)
+YY_BUFFER_STATE cmListFileLexer_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 {
 
-        return cmListFileLexer_yy_scan_bytes(yy_str,strlen(yy_str) ,yyscanner);
+        return cmListFileLexer_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
 }
 
 /** Setup the input buffer state to scan the given bytes. The next call to cmListFileLexer_yylex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE cmListFileLexer_yy_scan_bytes  (yyconst char * bytes, int  len , yyscan_t yyscanner)
+YY_BUFFER_STATE cmListFileLexer_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
 {
         YY_BUFFER_STATE b;
         char *buf;
@@ -1722,15 +1793,15 @@ YY_BUFFER_STATE cmListFileLexer_yy_scan_bytes  (yyconst char * bytes, int  len ,
         int i;
 
         /* Get memory for full buffer, including space for trailing EOB's. */
-        n = len + 2;
+        n = _yybytes_len + 2;
         buf = (char *) cmListFileLexer_yyalloc(n ,yyscanner );
         if ( ! buf )
                 YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yy_scan_bytes()" );
 
-        for ( i = 0; i < len; ++i )
-                buf[i] = bytes[i];
+        for ( i = 0; i < _yybytes_len; ++i )
+                buf[i] = yybytes[i];
 
-        buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+        buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
         b = cmListFileLexer_yy_scan_buffer(buf,n ,yyscanner);
         if ( ! b )
@@ -1918,21 +1989,87 @@ void cmListFileLexer_yyset_debug (int  bdebug , yyscan_t yyscanner)
 
 /* Accessor methods for yylval and yylloc */
 
+/* User-visible API */
+
+/* cmListFileLexer_yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int cmListFileLexer_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) cmListFileLexer_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmListFileLexer_yylex_init_extra has the same functionality as cmListFileLexer_yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to cmListFileLexer_yyalloc in
+ * the yyextra field.
+ */
+
+int cmListFileLexer_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    cmListFileLexer_yyset_extra (yy_user_defined, &dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) cmListFileLexer_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    cmListFileLexer_yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
 static int yy_init_globals (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     /* Initialization is the same as for the non-reentrant scanner.
-       This function is called once per scanner lifetime. */
+     * This function is called from cmListFileLexer_yylex_destroy(), so don't allocate here.
+     */
 
     yyg->yy_buffer_stack = 0;
     yyg->yy_buffer_stack_top = 0;
     yyg->yy_buffer_stack_max = 0;
     yyg->yy_c_buf_p = (char *) 0;
-    yyg->yy_init = 1;
+    yyg->yy_init = 0;
     yyg->yy_start = 0;
+
     yyg->yy_start_stack_ptr = 0;
     yyg->yy_start_stack_depth = 0;
-    yyg->yy_start_stack = (int *) 0;
+    yyg->yy_start_stack =  NULL;
 
 /* Defined in main.c */
 #ifdef YY_STDINIT
@@ -1949,33 +2086,6 @@ static int yy_init_globals (yyscan_t yyscanner)
     return 0;
 }
 
-/* User-visible API */
-
-/* cmListFileLexer_yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int cmListFileLexer_yylex_init(yyscan_t* ptr_yy_globals)
-
-{
-    if (ptr_yy_globals == NULL){
-        errno = EINVAL;
-        return 1;
-    }
-
-    *ptr_yy_globals = (yyscan_t) cmListFileLexer_yyalloc ( sizeof( struct yyguts_t ), NULL );
-
-    if (*ptr_yy_globals == NULL){
-        errno = ENOMEM;
-        return 1;
-    }
-
-    memset(*ptr_yy_globals,0,sizeof(struct yyguts_t));
-
-    return yy_init_globals ( *ptr_yy_globals );
-}
-
 /* cmListFileLexer_yylex_destroy is for both reentrant and non-reentrant scanners. */
 int cmListFileLexer_yylex_destroy  (yyscan_t yyscanner)
 {
@@ -1996,6 +2106,10 @@ int cmListFileLexer_yylex_destroy  (yyscan_t yyscanner)
         cmListFileLexer_yyfree(yyg->yy_start_stack ,yyscanner );
         yyg->yy_start_stack = NULL;
 
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * cmListFileLexer_yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
     /* Destroy the main struct (reentrant only). */
     cmListFileLexer_yyfree ( yyscanner , yyscanner );
     return 0;
@@ -2009,7 +2123,6 @@ int cmListFileLexer_yylex_destroy  (yyscan_t yyscanner)
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
 {
         int i;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
         for ( i = 0; i < n; ++i )
                 s1[i] = s2[i];
 }
@@ -2019,7 +2132,6 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
 static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 {
         int n;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
         for ( n = 0; s[n]; ++n )
                 ;
 
@@ -2054,19 +2166,7 @@ void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-#line 194 "cmListFileLexer.in.l"
+#line 192 "cmListFileLexer.in.l"
 
 
 
@@ -2122,7 +2222,7 @@ static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
     }
 
   /* We need to extend the buffer.  */
-  temp = (char*)malloc(newSize);
+  temp = malloc(newSize);
   if(lexer->token.text)
     {
     memcpy(temp, lexer->token.text, lexer->token.length);
@@ -2303,6 +2403,7 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
   switch(type)
     {
     case cmListFileLexer_Token_None: return "nothing";
+    case cmListFileLexer_Token_Space: return "space";
     case cmListFileLexer_Token_Newline: return "newline";
     case cmListFileLexer_Token_Identifier: return "identifier";
     case cmListFileLexer_Token_ParenLeft: return "left paren";

+ 1 - 0
Source/cmListFileLexer.h

@@ -15,6 +15,7 @@
 typedef enum cmListFileLexer_Type_e
 {
   cmListFileLexer_Token_None,
+  cmListFileLexer_Token_Space,
   cmListFileLexer_Token_Newline,
   cmListFileLexer_Token_Identifier,
   cmListFileLexer_Token_ParenLeft,

+ 23 - 3
Source/cmListFileLexer.in.l

@@ -24,6 +24,7 @@ Modify cmListFileLexer.c:
   - remove the yyunput function
   - add a statement "(void)yyscanner;" to the top of these methods:
       yy_fatal_error, cmListFileLexer_yyalloc, cmListFileLexer_yyrealloc, cmListFileLexer_yyfree
+  - remove statement "yyscanner = NULL;" from cmListFileLexer_yylex_destroy
   - remove all YY_BREAK lines occurring right after return statements
   - remove the isatty forward declaration
 
@@ -75,6 +76,8 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
 %x STRING
 
 MAKEVAR \$\([A-Za-z0-9_]*\)
+UNQUOTED ([^ \t\r\n\(\)#\\\"]|\\.)
+LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
 
 %%
 
@@ -111,7 +114,14 @@ MAKEVAR \$\([A-Za-z0-9_]*\)
   return 1;
 }
 
-({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.)({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.|\"({MAKEVAR}|[^\r\n\(\)#\\\"]|\\.)*\")* {
+({UNQUOTED})({UNQUOTED})* {
+  lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  cmListFileLexerSetToken(lexer, yytext, yyleng);
+  lexer->column += yyleng;
+  return 1;
+}
+
+({MAKEVAR}|{UNQUOTED})({LEGACY})* {
   lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
   cmListFileLexerSetToken(lexer, yytext, yyleng);
   lexer->column += yyleng;
@@ -125,11 +135,17 @@ MAKEVAR \$\([A-Za-z0-9_]*\)
   BEGIN(STRING);
 }
 
-<STRING>([^\\\n\"]|\\(.|\n))+ {
+<STRING>([^\\\n\"]|\\.)+ {
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
 
+<STRING>\\\n {
+  cmListFileLexerAppend(lexer, yytext, yyleng);
+  ++lexer->line;
+  lexer->column = 1;
+}
+
 <STRING>\n {
   cmListFileLexerAppend(lexer, yytext, yyleng);
   ++lexer->line;
@@ -153,8 +169,11 @@ MAKEVAR \$\([A-Za-z0-9_]*\)
   return 1;
 }
 
-[ \t\r] {
+[ \t\r]+ {
+  lexer->token.type = cmListFileLexer_Token_Space;
+  cmListFileLexerSetToken(lexer, yytext, yyleng);
   lexer->column += yyleng;
+  return 1;
 }
 
 . {
@@ -405,6 +424,7 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
   switch(type)
     {
     case cmListFileLexer_Token_None: return "nothing";
+    case cmListFileLexer_Token_Space: return "space";
     case cmListFileLexer_Token_Newline: return "newline";
     case cmListFileLexer_Token_Identifier: return "identifier";
     case cmListFileLexer_Token_ParenLeft: return "left paren";

+ 1 - 1
Source/cmMacroCommand.cxx

@@ -227,7 +227,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
         }
 
       arg.Value = tmps;
-      arg.Quoted = k->Quoted;
+      arg.Delim = k->Delim;
       arg.FilePath = k->FilePath;
       arg.Line = k->Line;
       newLFF.Arguments.push_back(arg);

+ 1 - 1
Source/cmMakefile.cxx

@@ -2840,7 +2840,7 @@ bool cmMakefile::ExpandArguments(
 
     // If the argument is quoted, it should be one argument.
     // Otherwise, it may be a list of arguments.
-    if(i->Quoted)
+    if(i->Delim == cmListFileArgument::Quoted)
       {
       outArgs.push_back(value);
       }

+ 10 - 5
Source/cmVariableWatchCommand.cxx

@@ -48,15 +48,20 @@ static void cmVariableWatchCommandVariableAccessed(
     {
     newLFF.Arguments.clear();
     newLFF.Arguments.push_back(
-      cmListFileArgument(variable, true, "unknown", 9999));
+      cmListFileArgument(variable, cmListFileArgument::Quoted,
+                         "unknown", 9999));
     newLFF.Arguments.push_back(
-      cmListFileArgument(accessString, true, "unknown", 9999));
+      cmListFileArgument(accessString, cmListFileArgument::Quoted,
+                         "unknown", 9999));
     newLFF.Arguments.push_back(
-      cmListFileArgument(newValue?newValue:"", true, "unknown", 9999));
+      cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted,
+                         "unknown", 9999));
     newLFF.Arguments.push_back(
-      cmListFileArgument(currentListFile, true, "unknown", 9999));
+      cmListFileArgument(currentListFile, cmListFileArgument::Quoted,
+                         "unknown", 9999));
     newLFF.Arguments.push_back(
-      cmListFileArgument(stack, true, "unknown", 9999));
+      cmListFileArgument(stack, cmListFileArgument::Quoted,
+                         "unknown", 9999));
     newLFF.Name = data->Command;
     newLFF.FilePath = "Some weird path";
     newLFF.Line = 9999;

+ 2 - 2
Source/cmWhileCommand.cxx

@@ -49,9 +49,9 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
           unsigned int i;
           for(i =0; i < this->Args.size(); ++i)
             {
-            err += (this->Args[i].Quoted?"\"":"");
+            err += (this->Args[i].Delim?"\"":"");
             err += this->Args[i].Value;
-            err += (this->Args[i].Quoted?"\"":"");
+            err += (this->Args[i].Delim?"\"":"");
             err += " ";
             }
           err += "(";

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -85,6 +85,7 @@ if(NOT WIN32)
   endif()
 endif()
 add_RunCMake_test(CompatibleInterface)
+add_RunCMake_test(Syntax)
 
 add_RunCMake_test(add_dependencies)
 add_RunCMake_test(build_command)

+ 1 - 0
Tests/RunCMake/Syntax/.gitattributes

@@ -0,0 +1 @@
+CommandTabs.cmake   whitespace=-tab-in-indent

+ 35 - 0
Tests/RunCMake/Syntax/BracketWarn-stderr.txt

@@ -0,0 +1,35 @@
+CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+  Syntax Warning in cmake code at
+
+    .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:16
+
+  A future version of CMake may treat unquoted argument:
+
+    \[\[
+
+  as an opening long bracket.  Double-quote the argument.
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+  Syntax Warning in cmake code at
+
+    .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:19
+
+  A future version of CMake may treat unquoted argument:
+
+    \[=\[
+
+  as an opening long bracket.  Double-quote the argument.
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+  Syntax Warning in cmake code at
+
+    .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:27
+
+  A future version of CMake may treat unquoted argument:
+
+    \[==\[x
+
+  as an opening long bracket.  Double-quote the argument.
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 1 - 0
Tests/RunCMake/Syntax/BracketWarn-stdout.txt

@@ -0,0 +1 @@
+-- \[\[\[=\[\[=x\[==\[x

+ 1 - 0
Tests/RunCMake/Syntax/BracketWarn.cmake

@@ -0,0 +1 @@
+message(STATUS [[ [=[ [=x [==[x)

+ 3 - 0
Tests/RunCMake/Syntax/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 4 - 0
Tests/RunCMake/Syntax/CommandComments-stderr.txt

@@ -0,0 +1,4 @@
+Example Message
+Example Message
+Example Message
+Second Line of Example

+ 6 - 0
Tests/RunCMake/Syntax/CommandComments.cmake

@@ -0,0 +1,6 @@
+message("Example Message"#)
+        )
+message ("Example Message" # )
+        )
+message( "Example Message\n" # "Commented" )
+         "Second Line of Example")

+ 1 - 0
Tests/RunCMake/Syntax/CommandError0-result.txt

@@ -0,0 +1 @@
+1

+ 8 - 0
Tests/RunCMake/Syntax/CommandError0-stderr.txt

@@ -0,0 +1,8 @@
+CMake Error: Error in cmake code at
+.*/Tests/RunCMake/Syntax/CommandError0.cmake:2:
+Parse error.  Expected "\(", got newline with text "
+".
+CMake Error at CMakeLists.txt:3 \(include\):
+  include could not find load file:
+
+    CommandError0.cmake

+ 2 - 0
Tests/RunCMake/Syntax/CommandError0.cmake

@@ -0,0 +1,2 @@
+message
+  ("Example Message")

+ 1 - 0
Tests/RunCMake/Syntax/CommandError1-result.txt

@@ -0,0 +1 @@
+1

+ 7 - 0
Tests/RunCMake/Syntax/CommandError1-stderr.txt

@@ -0,0 +1,7 @@
+CMake Error: Error in cmake code at
+.*/Tests/RunCMake/Syntax/CommandError1.cmake:1:
+Parse error.  Expected a newline, got identifier with text "message".
+CMake Error at CMakeLists.txt:3 \(include\):
+  include could not find load file:
+
+    CommandError1.cmake

+ 1 - 0
Tests/RunCMake/Syntax/CommandError1.cmake

@@ -0,0 +1 @@
+message("Example Message") message("Second Message")

+ 3 - 0
Tests/RunCMake/Syntax/CommandNewlines-stderr.txt

@@ -0,0 +1,3 @@
+Example Message
+Example Message
+Example Message

+ 10 - 0
Tests/RunCMake/Syntax/CommandNewlines.cmake

@@ -0,0 +1,10 @@
+message(
+  "Example Message")
+message (
+  "Example Message"
+  )
+message(
+
+  "Example Message"
+
+  )

+ 6 - 0
Tests/RunCMake/Syntax/CommandSpaces-stderr.txt

@@ -0,0 +1,6 @@
+Example Message
+Example Message
+Example Message
+Example Message
+Example Message
+Example Message

+ 6 - 0
Tests/RunCMake/Syntax/CommandSpaces.cmake

@@ -0,0 +1,6 @@
+message("Example Message")
+message ("Example Message")
+message( "Example Message" )
+message( "Example Message")
+  message  ( "Example Message")
+message ( Example " " Message )

+ 6 - 0
Tests/RunCMake/Syntax/CommandTabs-stderr.txt

@@ -0,0 +1,6 @@
+Example Message
+Example Message
+Example Message
+Example Message
+Example Message
+Example Message

+ 6 - 0
Tests/RunCMake/Syntax/CommandTabs.cmake

@@ -0,0 +1,6 @@
+message("Example Message")
+message	("Example Message")
+message(	"Example Message"	)
+message(	"Example Message")
+	message (	"Example Message")
+message	(	Example	" "	Message	)

+ 17 - 0
Tests/RunCMake/Syntax/RunCMakeTest.cmake

@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(CommandSpaces)
+run_cmake(CommandTabs)
+run_cmake(CommandNewlines)
+run_cmake(CommandComments)
+run_cmake(CommandError0)
+run_cmake(CommandError1)
+run_cmake(String0)
+run_cmake(String1)
+run_cmake(StringNoSpace)
+run_cmake(Unquoted0)
+run_cmake(Unquoted1)
+run_cmake(UnterminatedCall1)
+run_cmake(UnterminatedCall2)
+run_cmake(UnterminatedString)
+run_cmake(BracketWarn)

+ 1 - 0
Tests/RunCMake/Syntax/String0-stderr.txt

@@ -0,0 +1 @@
+^1 2;3 4$

+ 2 - 0
Tests/RunCMake/Syntax/String0.cmake

@@ -0,0 +1,2 @@
+set(var 2 3)
+message("1 ${var} 4")

+ 3 - 0
Tests/RunCMake/Syntax/String1-stderr.txt

@@ -0,0 +1,3 @@
+^
+  1 \${var} 4
+ $

+ 3 - 0
Tests/RunCMake/Syntax/String1.cmake

@@ -0,0 +1,3 @@
+message("
+  1 \${var} 4
+ ")

+ 19 - 0
Tests/RunCMake/Syntax/StringNoSpace-stderr.txt

@@ -0,0 +1,19 @@
+CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+  Syntax Warning in cmake code at
+
+    .*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:28
+
+  Argument not separated from preceding token by whitespace.
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+  Syntax Warning in cmake code at
+
+    .*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:31
+
+  Argument not separated from preceding token by whitespace.
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+\[1 \${var} \\n 4\]
+\[x\]
+\[y\]$

+ 4 - 0
Tests/RunCMake/Syntax/StringNoSpace.cmake

@@ -0,0 +1,4 @@
+# Quoted arguments may be immediately followed by another argument.
+foreach(x "1 \${var} \\n 4""x"y)
+  message("[${x}]")
+endforeach()

+ 1 - 0
Tests/RunCMake/Syntax/Unquoted0-stderr.txt

@@ -0,0 +1 @@
+^1234$

+ 2 - 0
Tests/RunCMake/Syntax/Unquoted0.cmake

@@ -0,0 +1,2 @@
+set(var 2 3)
+message(1 ${var} 4)

+ 1 - 0
Tests/RunCMake/Syntax/Unquoted1-stderr.txt

@@ -0,0 +1 @@
+^\[\]\[=\]\[\$\$\(MV\)-DSTR=" \[="\[;\]$

+ 1 - 0
Tests/RunCMake/Syntax/Unquoted1.cmake

@@ -0,0 +1 @@
+message([] [=] [$ $(MV) -DSTR=" [=" [;])

+ 1 - 0
Tests/RunCMake/Syntax/UnterminatedCall1-result.txt

@@ -0,0 +1 @@
+1

+ 7 - 0
Tests/RunCMake/Syntax/UnterminatedCall1-stderr.txt

@@ -0,0 +1,7 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedCall1.cmake:2:
+Parse error.  Function missing ending "\)".  End of file reached.
+CMake Error at CMakeLists.txt:3 \(include\):
+  include could not find load file:
+
+    UnterminatedCall1.cmake

+ 1 - 0
Tests/RunCMake/Syntax/UnterminatedCall1.cmake

@@ -0,0 +1 @@
+message(

+ 1 - 0
Tests/RunCMake/Syntax/UnterminatedCall2-result.txt

@@ -0,0 +1 @@
+1

+ 7 - 0
Tests/RunCMake/Syntax/UnterminatedCall2-stderr.txt

@@ -0,0 +1,7 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedCall2.cmake:4:
+Parse error.  Function missing ending "\)".  End of file reached.
+CMake Error at CMakeLists.txt:3 \(include\):
+  include could not find load file:
+
+    UnterminatedCall2.cmake

+ 3 - 0
Tests/RunCMake/Syntax/UnterminatedCall2.cmake

@@ -0,0 +1,3 @@
+set(var "\
+")
+message(

+ 1 - 0
Tests/RunCMake/Syntax/UnterminatedString-result.txt

@@ -0,0 +1 @@
+1

+ 8 - 0
Tests/RunCMake/Syntax/UnterminatedString-stderr.txt

@@ -0,0 +1,8 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedString.cmake:2:
+Parse error.  Function missing ending "\)".  Instead found unterminated string with text "\)
+".
+CMake Error at CMakeLists.txt:3 \(include\):
+  include could not find load file:
+
+    UnterminatedString.cmake$

+ 1 - 0
Tests/RunCMake/Syntax/UnterminatedString.cmake

@@ -0,0 +1 @@
+set(var ")