summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt12
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cpack.cxx13
-rw-r--r--Source/CursesDialog/ccmake.cxx2
-rw-r--r--Source/QtDialog/CMakeSetup.cxx7
-rw-r--r--Source/cmCoreTryCompile.cxx4
-rw-r--r--Source/cmDocumentation.cxx44
-rw-r--r--Source/cmDocumentation.h2
-rw-r--r--Source/cmExecProgramCommand.cxx196
-rw-r--r--Source/cmExecProgramCommand.h4
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx43
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h7
-rw-r--r--Source/cmIncludeCommand.cxx2
-rw-r--r--Source/cmListFileCache.cxx95
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmListFileLexer.c462
-rw-r--r--Source/cmListFileLexer.h17
-rw-r--r--Source/cmListFileLexer.in.l190
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx30
-rw-r--r--Source/cmMakefile.cxx6
-rw-r--r--Source/cmPolicies.cxx438
-rw-r--r--Source/cmPolicies.h3
-rw-r--r--Source/cmRST.cxx2
-rw-r--r--Source/cmSystemTools.cxx358
-rw-r--r--Source/cmSystemTools.h27
-rw-r--r--Source/cmTarget.cxx52
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx6
-rw-r--r--Source/cmWin32ProcessExecution.cxx884
-rw-r--r--Source/cmWin32ProcessExecution.h169
-rw-r--r--Source/cmake.cxx4
-rw-r--r--Source/cmakemain.cxx77
-rw-r--r--Source/cmcmd.cxx14
-rw-r--r--Source/cmw9xcom.cxx45
-rw-r--r--Source/ctest.cxx12
35 files changed, 1004 insertions, 2230 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 71fae58..7efaa50 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -363,8 +363,6 @@ if (WIN32)
cmVisualStudioSlnParser.cxx
cmVisualStudioWCEPlatformParser.h
cmVisualStudioWCEPlatformParser.cxx
- cmWin32ProcessExecution.cxx
- cmWin32ProcessExecution.h
)
endif()
endif ()
@@ -540,16 +538,6 @@ endif()
add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h)
target_link_libraries(cmake CMakeLib)
-# Build special executable for running programs on Windows 98.
-# Included on any Windows (unconditional packaging required!).
-if(WIN32)
- if(NOT UNIX)
- add_executable(cmw9xcom cmw9xcom.cxx)
- target_link_libraries(cmw9xcom CMakeLib)
- install(TARGETS cmw9xcom DESTINATION bin)
- endif()
-endif()
-
# Build CTest executable
add_executable(ctest ctest.cxx)
target_link_libraries(ctest CTestLib)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 833903e..a44f362 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -2,5 +2,5 @@
set(CMake_VERSION_MAJOR 2)
set(CMake_VERSION_MINOR 8)
set(CMake_VERSION_PATCH 12)
-set(CMake_VERSION_TWEAK 20131016)
+set(CMake_VERSION_TWEAK 20131021)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 677f5b1..9f8cc14 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -55,13 +55,6 @@ static const char * cmDocumentationOptions[][2] =
{"-R <package version>","override/define CPACK_PACKAGE_VERSION"},
{"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY"},
{"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR"},
- {"--help-command cmd [file]", "Print help for a single command and exit."},
- {"--help-command-list [file]", "List available commands and exit."},
- {"--help-commands [file]", "Print help for all commands and exit."},
- {"--help-variable var [file]",
- "Print help for a single variable and exit."},
- {"--help-variable-list [file]", "List documented variables and exit."},
- {"--help-variables [file]", "Print help for all variables and exit."},
{0,0}
};
@@ -235,6 +228,7 @@ int main (int argc, char *argv[])
// This part is used for cpack documentation lookup as well.
cminst.AddCMakePaths();
+ doc.SetCMakeRoot(cminst.GetCacheDefinition("CMAKE_ROOT"));
if ( parsed && !help )
{
@@ -409,11 +403,6 @@ int main (int argc, char *argv[])
}
if ( parsed )
{
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
-
const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: "
<< cpackGenerator->GetNameOfClass() << std::endl);
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 3855d53..fdfe331 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -86,6 +86,8 @@ int main(int argc, char** argv)
if(doc.CheckOptions(argc, argv))
{
cmake hcm;
+ hcm.AddCMakePaths();
+ doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
std::vector<cmDocumentationEntry> generators;
hcm.GetGeneratorDocumentation(generators);
doc.SetName("ccmake");
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index cfefab2..095aeb6 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -58,12 +58,7 @@ int main(int argc, char** argv)
// Construct and print requested documentation.
cmake hcm;
hcm.AddCMakePaths();
- // just incase the install is bad avoid a seg fault
- const char* root = hcm.GetCacheDefinition("CMAKE_ROOT");
- if(root)
- {
- doc.SetCMakeRoot(root);
- }
+ doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
std::vector<cmDocumentationEntry> generators;
hcm.GetGeneratorDocumentation(generators);
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index bc4bf18..0ac969b 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -372,8 +372,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
}
/* for the TRY_COMPILEs we want to be able to specify the architecture.
- So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set
- CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to
+ So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
+ CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
have the tests run for each specific architecture. Since
cmLocalGenerator doesn't allow building for "the other"
architecture only via CMAKE_OSX_ARCHITECTURES.
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 2d7feab..682478e 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -25,12 +25,44 @@
//----------------------------------------------------------------------------
static const char *cmDocumentationStandardOptions[][2] =
{
- {"--copyright [file]", "Print the CMake copyright and exit."},
- {"--help,-help,-usage,-h,-H,/?", "Print usage information and exit."},
- {"--help-full [file]", "Print full help and exit."},
- {"--help-html [file]", "Print full help in HTML format."},
- {"--help-man [file]", "Print full help as a UNIX man page and exit."},
- {"--version,-version,/V [file]"},
+ {"--help,-help,-usage,-h,-H,/?",
+ "Print usage information and exit."},
+ {"--version,-version,/V [<f>]",
+ "Print version number and exit."},
+ {"--help-manual <man> [<f>]",
+ "Print one help manual and exit."},
+ {"--help-manual-list [<f>]",
+ "List help manuals available and exit."},
+ {"--help-command <cmd> [<f>]",
+ "Print help for one command and exit."},
+ {"--help-command-list [<f>]",
+ "List commands with help available and exit."},
+ {"--help-commands [<f>]",
+ "Print cmake-commands manual and exit."},
+ {"--help-module <mod> [<f>]",
+ "Print help for one module and exit."},
+ {"--help-module-list [<f>]",
+ "List modules with help available and exit."},
+ {"--help-modules [<f>]",
+ "Print cmake-modules manual and exit."},
+ {"--help-policy <cmp> [<f>]",
+ "Print help for one policy and exit."},
+ {"--help-policy-list [<f>]",
+ "List policies with help available and exit."},
+ {"--help-policies [<f>]",
+ "Print cmake-policies manual and exit."},
+ {"--help-property <prop> [<f>]",
+ "Print help for one property and exit."},
+ {"--help-property-list [<f>]",
+ "List properties with help available and exit."},
+ {"--help-properties [<f>]",
+ "Print cmake-properties manual and exit."},
+ {"--help-variable var [<f>]",
+ "Print help for one variable and exit."},
+ {"--help-variable-list [<f>]",
+ "List variables with help available and exit."},
+ {"--help-variables [<f>]",
+ "Print cmake-variables manual and exit."},
{0,0}
};
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index a4072c5..07e614d 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -84,7 +84,7 @@ public:
cmDocumentationEntry &docs);
/** Set cmake root so we can find installed files */
- void SetCMakeRoot(const char* root) { this->CMakeRoot = root;}
+ void SetCMakeRoot(const char* root) { this->CMakeRoot = root? root:"";}
/** Add common (to all tools) documentation section(s) */
void addCommonStandardDocSections();
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 9fdb1e8..6c11345 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -12,6 +12,8 @@
#include "cmExecProgramCommand.h"
#include "cmSystemTools.h"
+#include <cmsys/Process.h>
+
// cmExecProgramCommand
bool cmExecProgramCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -103,13 +105,13 @@ bool cmExecProgramCommand
if(args.size() - count == 2)
{
cmSystemTools::MakeDirectory(args[1].c_str());
- result = cmSystemTools::RunCommand(command.c_str(), output, retVal,
- args[1].c_str(), verbose);
+ result = cmExecProgramCommand::RunCommand(command.c_str(), output, retVal,
+ args[1].c_str(), verbose);
}
else
{
- result = cmSystemTools::RunCommand(command.c_str(), output,
- retVal, 0, verbose);
+ result = cmExecProgramCommand::RunCommand(command.c_str(), output,
+ retVal, 0, verbose);
}
if(!result)
{
@@ -143,3 +145,189 @@ bool cmExecProgramCommand
return true;
}
+bool cmExecProgramCommand::RunCommand(const char* command,
+ std::string& output,
+ int &retVal,
+ const char* dir,
+ bool verbose)
+{
+ if(cmSystemTools::GetRunCommandOutput())
+ {
+ verbose = false;
+ }
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+ // if the command does not start with a quote, then
+ // try to find the program, and if the program can not be
+ // found use system to run the command as it must be a built in
+ // shell command like echo or dir
+ int count = 0;
+ std::string shortCmd;
+ if(command[0] == '\"')
+ {
+ // count the number of quotes
+ for(const char* s = command; *s != 0; ++s)
+ {
+ if(*s == '\"')
+ {
+ count++;
+ if(count > 2)
+ {
+ break;
+ }
+ }
+ }
+ // if there are more than two double quotes use
+ // GetShortPathName, the cmd.exe program in windows which
+ // is used by system fails to execute if there are more than
+ // one set of quotes in the arguments
+ if(count > 2)
+ {
+ cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
+ if(quoted.find(command))
+ {
+ std::string cmd = quoted.match(1);
+ std::string args = quoted.match(2);
+ if(! cmSystemTools::FileExists(cmd.c_str()) )
+ {
+ shortCmd = cmd;
+ }
+ else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
+ {
+ cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
+ return false;
+ }
+ shortCmd += " ";
+ shortCmd += args;
+
+ command = shortCmd.c_str();
+ }
+ else
+ {
+ cmSystemTools::Error("Could not parse command line with quotes ",
+ command);
+ }
+ }
+ }
+#endif
+
+ // Allocate a process instance.
+ cmsysProcess* cp = cmsysProcess_New();
+ if(!cp)
+ {
+ cmSystemTools::Error("Error allocating process instance.");
+ return false;
+ }
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+ if(dir)
+ {
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ }
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
+ const char* cmd[] = {command, 0};
+ cmsysProcess_SetCommand(cp, cmd);
+#else
+ std::string commandInDir;
+ if(dir)
+ {
+ commandInDir = "cd \"";
+ commandInDir += dir;
+ commandInDir += "\" && ";
+ commandInDir += command;
+ }
+ else
+ {
+ commandInDir = command;
+ }
+#ifndef __VMS
+ commandInDir += " 2>&1";
+#endif
+ command = commandInDir.c_str();
+ if(verbose)
+ {
+ cmSystemTools::Stdout("running ");
+ cmSystemTools::Stdout(command);
+ cmSystemTools::Stdout("\n");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ const char* cmd[] = {"/bin/sh", "-c", command, 0};
+ cmsysProcess_SetCommand(cp, cmd);
+#endif
+
+ cmsysProcess_Execute(cp);
+
+ // Read the process output.
+ int length;
+ char* data;
+ int p;
+ while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p))
+ {
+ if(p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR)
+ {
+ if(verbose)
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ output.append(data, length);
+ }
+ }
+
+ // All output has been read. Wait for the process to exit.
+ cmsysProcess_WaitForExit(cp, 0);
+
+ // Check the result of running the process.
+ std::string msg;
+ switch(cmsysProcess_GetState(cp))
+ {
+ case cmsysProcess_State_Exited:
+ retVal = cmsysProcess_GetExitValue(cp);
+ break;
+ case cmsysProcess_State_Exception:
+ retVal = -1;
+ msg += "\nProcess terminated due to: ";
+ msg += cmsysProcess_GetExceptionString(cp);
+ break;
+ case cmsysProcess_State_Error:
+ retVal = -1;
+ msg += "\nProcess failed because: ";
+ msg += cmsysProcess_GetErrorString(cp);
+ break;
+ case cmsysProcess_State_Expired:
+ retVal = -1;
+ msg += "\nProcess terminated due to timeout.";
+ break;
+ }
+ if(!msg.empty())
+ {
+#if defined(WIN32) && !defined(__CYGWIN__)
+ // Old Windows process execution printed this info.
+ msg += "\n\nfor command: ";
+ msg += command;
+ if(dir)
+ {
+ msg += "\nin dir: ";
+ msg += dir;
+ }
+ msg += "\n";
+ if(verbose)
+ {
+ cmSystemTools::Stdout(msg.c_str());
+ }
+ output += msg;
+#else
+ // Old UNIX process execution only put message in output.
+ output += msg;
+#endif
+ }
+
+ // Delete the process instance.
+ cmsysProcess_Delete(cp);
+
+ return true;
+}
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index 4892dd8..6d28cdc 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -57,6 +57,10 @@ public:
}
cmTypeMacro(cmExecProgramCommand, cmCommand);
+private:
+ static bool RunCommand(const char* command, std::string& output,
+ int &retVal, const char* directory = 0,
+ bool verbose = true);
};
#endif
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index bd3d669..a2dd903 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -1132,7 +1132,7 @@ cmExtraEclipseCDT4Generator::GetEclipsePath(const std::string& path)
#if defined(__CYGWIN__)
std::string cmd = "cygpath -m " + path;
std::string out;
- if (!cmSystemTools::RunCommand(cmd.c_str(), out, 0, false))
+ if (!cmSystemTools::RunSingleCommand(cmd.c_str(), &out))
{
return path;
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 0b9796d..d476c24 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -21,6 +21,7 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
const char* platformName)
{
this->FindMakeProgramFile = "CMakeVS7FindMake.cmake";
+ this->IntelProjectVersion = 0;
if (!platformName)
{
@@ -29,6 +30,45 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
this->PlatformName = platformName;
}
+cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
+{
+ free(this->IntelProjectVersion);
+}
+
+// Package GUID of Intel Visual Fortran plugin to VS IDE
+#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
+
+const char* cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
+{
+ if(!this->IntelProjectVersion)
+ {
+ // Compute the version of the Intel plugin to the VS IDE.
+ // If the key does not exist then use a default guess.
+ std::string intelVersion;
+ std::string vskey = this->GetRegistryBase();
+ vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
+ cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
+ cmSystemTools::KeyWOW64_32);
+ unsigned int intelVersionNumber = ~0u;
+ sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
+ if(intelVersionNumber >= 11)
+ {
+ // Default to latest known project file version.
+ intelVersion = "11.0";
+ }
+ else if(intelVersionNumber == 10)
+ {
+ // Version 10.x actually uses 9.10 in project files!
+ intelVersion = "9.10";
+ }
+ else
+ {
+ // Version <= 9: use ProductVersion from registry.
+ }
+ this->IntelProjectVersion = strdup(intelVersion.c_str());
+ }
+ return this->IntelProjectVersion;
+}
void cmGlobalVisualStudio7Generator
::EnableLanguage(std::vector<std::string>const & lang,
@@ -36,7 +76,6 @@ void cmGlobalVisualStudio7Generator
{
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
- mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort");
this->AddPlatformDefinitions(mf);
if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
@@ -156,6 +195,8 @@ void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf)
{
cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
+ mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
+ this->GetIntelProjectVersion());
}
void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 4d22cff..66dc443 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -27,6 +27,8 @@ class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator
{
public:
cmGlobalVisualStudio7Generator(const char* platformName = NULL);
+ ~cmGlobalVisualStudio7Generator();
+
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalVisualStudio7Generator>(); }
@@ -101,6 +103,8 @@ public:
LinkLibraryDependencies and link to .sln dependencies. */
virtual bool NeedLinkLibraryDependencies(cmTarget&) { return false; }
+ const char* GetIntelProjectVersion();
+
protected:
virtual const char* GetIDEVersion() { return "7.0"; }
@@ -159,6 +163,9 @@ protected:
// There is one SLN file per project.
std::string CurrentProject;
std::string PlatformName;
+
+private:
+ char* IntelProjectVersion;
};
#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 5b93171..e8ee33f 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -19,7 +19,7 @@ bool cmIncludeCommand
if (args.size()< 1 || args.size() > 4)
{
this->SetError("called with wrong number of arguments. "
- "Include only takes one file.");
+ "include() only takes one file.");
return false;
}
bool optional = false;
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 898f379..7461d37 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -29,14 +29,14 @@ struct cmListFileParser
~cmListFileParser();
bool ParseFile();
bool ParseFunction(const char* name, long line);
- void AddArgument(cmListFileLexer_Token* token,
+ bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
cmListFile* ListFile;
cmMakefile* Makefile;
const char* FileName;
cmListFileLexer* Lexer;
cmListFileFunction Function;
- enum { SeparationOkay, SeparationWarning } Separation;
+ enum { SeparationOkay, SeparationWarning, SeparationError} Separation;
};
//----------------------------------------------------------------------------
@@ -57,13 +57,26 @@ cmListFileParser::~cmListFileParser()
bool cmListFileParser::ParseFile()
{
// Open the file.
- if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName))
+ cmListFileLexer_BOM bom;
+ if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom))
{
cmSystemTools::Error("cmListFileCache: error can not open file ",
this->FileName);
return false;
}
+ // Verify the Byte-Order-Mark, if any.
+ if(bom != cmListFileLexer_BOM_None &&
+ bom != cmListFileLexer_BOM_UTF8)
+ {
+ cmListFileLexer_SetFileName(this->Lexer, 0, 0);
+ cmOStringStream m;
+ m << "File\n " << this->FileName << "\n"
+ << "starts with a Byte-Order-Mark that is not UTF-8.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str());
+ return false;
+ }
+
// Use a simple recursive-descent parser to process the token
// stream.
bool haveNewline = true;
@@ -77,6 +90,10 @@ bool cmListFileParser::ParseFile()
{
haveNewline = true;
}
+ else if(token->type == cmListFileLexer_Token_CommentBracket)
+ {
+ haveNewline = false;
+ }
else if(token->type == cmListFileLexer_Token_Identifier)
{
if(haveNewline)
@@ -288,7 +305,10 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
{
parenDepth++;
this->Separation = SeparationOkay;
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
}
else if(token->type == cmListFileLexer_Token_ParenRight)
{
@@ -298,20 +318,41 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
parenDepth--;
this->Separation = SeparationOkay;
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_Identifier ||
token->type == cmListFileLexer_Token_ArgumentUnquoted)
{
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
{
- this->AddArgument(token, cmListFileArgument::Quoted);
+ if(!this->AddArgument(token, cmListFileArgument::Quoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
+ else if(token->type == cmListFileLexer_Token_ArgumentBracket)
+ {
+ if(!this->AddArgument(token, cmListFileArgument::Bracket))
+ {
+ return false;
+ }
+ this->Separation = SeparationError;
+ }
+ else if(token->type == cmListFileLexer_Token_CommentBracket)
+ {
+ this->Separation = SeparationError;
+ }
else
{
// Error.
@@ -338,42 +379,32 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
//----------------------------------------------------------------------------
-void cmListFileParser::AddArgument(cmListFileLexer_Token* token,
+bool 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;
+ return true;
}
+ bool isError = (this->Separation == SeparationError ||
+ delim == cmListFileArgument::Bracket);
cmOStringStream m;
- m << "Syntax Warning in cmake code at\n"
+ m << "Syntax " << (isError? "Error":"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());
+ if(isError)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str().c_str());
+ return false;
+ }
+ else
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
+ return true;
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 7bb3b34..bede25e 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -28,7 +28,8 @@ struct cmListFileArgument
enum Delimiter
{
Unquoted,
- Quoted
+ Quoted,
+ Bracket
};
cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {}
cmListFileArgument(const cmListFileArgument& r):
diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c
index f127add..3b08b03 100644
--- a/Source/cmListFileLexer.c
+++ b/Source/cmListFileLexer.c
@@ -369,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 16
-#define YY_END_OF_BUFFER 17
+#define YY_NUM_RULES 23
+#define YY_END_OF_BUFFER 24
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -378,13 +378,16 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[45] =
+static yyconst flex_int16_t yy_accept[77] =
{ 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
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 4,
+ 24, 13, 21, 1, 15, 3, 13, 5, 6, 7,
+ 22, 22, 16, 18, 19, 20, 10, 11, 8, 12,
+ 9, 4, 13, 0, 13, 0, 21, 0, 0, 7,
+ 13, 0, 13, 0, 2, 0, 13, 16, 0, 17,
+ 10, 8, 4, 0, 14, 0, 0, 0, 0, 14,
+ 0, 0, 14, 0, 0, 0, 2, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -395,14 +398,14 @@ static yyconst flex_int32_t yy_ec[256] =
1, 2, 1, 5, 6, 7, 1, 1, 1, 8,
9, 1, 1, 1, 1, 1, 1, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 1, 1, 1,
- 1, 1, 1, 1, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 1, 12, 1, 1, 11, 1, 11, 11, 11, 11,
-
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 1, 1, 1, 1, 1, 1, 1, 1,
+ 11, 1, 1, 1, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 14, 15, 1, 12, 1, 12, 12, 12, 12,
+
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -419,72 +422,111 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[13] =
+static yyconst flex_int32_t yy_meta[16] =
{ 0,
- 1, 2, 3, 2, 4, 1, 1, 1, 5, 5,
- 5, 1
+ 1, 1, 2, 3, 4, 3, 1, 3, 5, 6,
+ 1, 6, 1, 1, 7
} ;
-static yyconst flex_int16_t yy_base[56] =
+static yyconst flex_int16_t yy_base[95] =
{ 0,
- 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
+ 0, 0, 13, 25, 14, 16, 17, 18, 90, 88,
+ 88, 39, 20, 237, 237, 74, 78, 237, 237, 13,
+ 54, 0, 71, 237, 237, 31, 0, 237, 73, 237,
+ 237, 0, 0, 65, 75, 0, 33, 30, 72, 0,
+ 0, 75, 70, 0, 74, 0, 0, 62, 70, 237,
+ 0, 63, 0, 85, 99, 65, 111, 62, 34, 0,
+ 54, 116, 0, 54, 127, 51, 237, 50, 0, 48,
+ 47, 39, 33, 29, 17, 237, 136, 143, 150, 157,
+ 164, 171, 178, 184, 191, 198, 201, 207, 214, 217,
+ 219, 225, 228, 230
+
} ;
-static yyconst flex_int16_t yy_def[56] =
+static yyconst flex_int16_t yy_def[95] =
{ 0,
- 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
+ 76, 1, 77, 77, 78, 78, 79, 79, 80, 80,
+ 76, 76, 76, 76, 76, 76, 12, 76, 76, 12,
+ 76, 81, 82, 76, 76, 82, 83, 76, 76, 76,
+ 76, 84, 12, 85, 12, 86, 76, 76, 87, 20,
+ 12, 88, 12, 21, 76, 89, 12, 82, 82, 76,
+ 83, 76, 84, 85, 76, 54, 85, 90, 76, 55,
+ 87, 88, 55, 62, 88, 91, 76, 55, 92, 93,
+ 90, 94, 91, 93, 94, 0, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76
+
} ;
-static yyconst flex_int16_t yy_nxt[122] =
+static yyconst flex_int16_t yy_nxt[253] =
{ 0,
- 6, 7, 8, 7, 9, 10, 11, 12, 13, 6,
- 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
+ 12, 13, 14, 13, 15, 16, 17, 18, 19, 12,
+ 12, 20, 21, 22, 12, 24, 28, 25, 28, 28,
+ 28, 37, 40, 37, 40, 62, 26, 24, 29, 25,
+ 29, 31, 31, 50, 37, 48, 37, 54, 26, 33,
+ 59, 63, 45, 34, 59, 35, 45, 62, 33, 33,
+ 33, 33, 36, 33, 41, 55, 54, 58, 42, 63,
+ 43, 72, 60, 41, 44, 41, 45, 46, 41, 55,
+ 55, 56, 70, 52, 48, 49, 67, 66, 57, 63,
+ 60, 64, 58, 52, 49, 39, 38, 76, 65, 55,
+ 14, 56, 14, 76, 76, 76, 76, 76, 57, 55,
+
+ 76, 76, 76, 34, 76, 68, 76, 76, 55, 55,
+ 55, 55, 69, 55, 54, 76, 54, 76, 54, 54,
+ 63, 76, 64, 76, 76, 76, 76, 76, 76, 65,
+ 62, 76, 62, 76, 62, 62, 23, 23, 23, 23,
+ 23, 23, 23, 27, 27, 27, 27, 27, 27, 27,
+ 30, 30, 30, 30, 30, 30, 30, 32, 32, 32,
+ 32, 32, 32, 32, 47, 76, 47, 47, 47, 47,
+ 47, 48, 76, 48, 76, 48, 48, 48, 51, 76,
+ 51, 51, 51, 51, 53, 76, 53, 53, 53, 53,
+ 53, 54, 76, 76, 54, 76, 54, 54, 33, 76,
+
+ 33, 33, 33, 33, 33, 61, 61, 62, 76, 76,
+ 62, 76, 62, 62, 41, 76, 41, 41, 41, 41,
+ 41, 71, 71, 73, 73, 55, 76, 55, 55, 55,
+ 55, 55, 74, 74, 75, 75, 11, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76
} ;
-static yyconst flex_int16_t yy_chk[122] =
+static yyconst flex_int16_t yy_chk[253] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 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, 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
+ 1, 1, 1, 1, 1, 3, 5, 3, 6, 7,
+ 8, 13, 20, 13, 20, 75, 3, 4, 5, 4,
+ 6, 7, 8, 26, 37, 26, 37, 74, 4, 12,
+ 38, 73, 38, 12, 59, 12, 59, 72, 12, 12,
+ 12, 12, 12, 12, 21, 71, 70, 68, 21, 66,
+ 21, 64, 61, 21, 21, 21, 21, 21, 21, 34,
+ 58, 34, 56, 52, 49, 48, 45, 43, 34, 42,
+ 39, 42, 35, 29, 23, 17, 16, 11, 42, 54,
+ 10, 54, 9, 0, 0, 0, 0, 0, 54, 55,
+
+ 0, 0, 0, 55, 0, 55, 0, 0, 55, 55,
+ 55, 55, 55, 55, 57, 0, 57, 0, 57, 57,
+ 62, 0, 62, 0, 0, 0, 0, 0, 0, 62,
+ 65, 0, 65, 0, 65, 65, 77, 77, 77, 77,
+ 77, 77, 77, 78, 78, 78, 78, 78, 78, 78,
+ 79, 79, 79, 79, 79, 79, 79, 80, 80, 80,
+ 80, 80, 80, 80, 81, 0, 81, 81, 81, 81,
+ 81, 82, 0, 82, 0, 82, 82, 82, 83, 0,
+ 83, 83, 83, 83, 84, 0, 84, 84, 84, 84,
+ 84, 85, 0, 0, 85, 0, 85, 85, 86, 0,
+
+ 86, 86, 86, 86, 86, 87, 87, 88, 0, 0,
+ 88, 0, 88, 88, 89, 0, 89, 89, 89, 89,
+ 89, 90, 90, 91, 91, 92, 0, 92, 92, 92,
+ 92, 92, 93, 93, 94, 94, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[17] =
+static yyconst flex_int32_t yy_rule_can_match_eol[24] =
{ 0,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, };
+1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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.
@@ -538,10 +580,13 @@ Modify cmListFileLexer.c:
struct cmListFileLexer_s
{
cmListFileLexer_Token token;
+ int bracket;
+ int comment;
int line;
int column;
int size;
FILE* file;
+ size_t cr;
char* string_buffer;
char* string_position;
int string_left;
@@ -564,10 +609,16 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
/*--------------------------------------------------------------------------*/
-#line 570 "cmListFileLexer.c"
+
+
+
+#line 618 "cmListFileLexer.c"
#define INITIAL 0
#define STRING 1
+#define BRACKET 2
+#define BRACKETEND 3
+#define COMMENT 4
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
@@ -793,10 +844,10 @@ YY_DECL
int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 82 "cmListFileLexer.in.l"
+#line 88 "cmListFileLexer.in.l"
-#line 804 "cmListFileLexer.c"
+#line 855 "cmListFileLexer.c"
if ( !yyg->yy_init )
{
@@ -849,13 +900,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 >= 45 )
+ if ( yy_current_state >= 77 )
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] != 109 );
+ while ( yy_base[yy_current_state] != 237 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -894,69 +945,168 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 84 "cmListFileLexer.in.l"
+#line 90 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Newline;
cmListFileLexerSetToken(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
+ BEGIN(INITIAL);
return 1;
}
case 2:
+/* rule 2 can match eol */
YY_RULE_SETUP
-#line 92 "cmListFileLexer.in.l"
+#line 99 "cmListFileLexer.in.l"
{
- lexer->column += yyleng;
+ const char* bracket = yytext;
+ lexer->comment = yytext[0] == '#';
+ if(lexer->comment)
+ {
+ lexer->token.type = cmListFileLexer_Token_CommentBracket;
+ bracket += 1;
+ }
+ else
+ {
+ lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
+ }
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->bracket = (int)(strchr(bracket+1, '[') - bracket);
+ if(yytext[yyleng-1] == '\n')
+ {
+ ++lexer->line;
+ lexer->column = 1;
+ }
+ else
+ {
+ lexer->column += yyleng;
+ }
+ BEGIN(BRACKET);
}
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 96 "cmListFileLexer.in.l"
+#line 125 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+ BEGIN(COMMENT);
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 130 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 134 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ParenLeft;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 4:
+case 6:
YY_RULE_SETUP
-#line 103 "cmListFileLexer.in.l"
+#line 141 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ParenRight;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 5:
+case 7:
YY_RULE_SETUP
-#line 110 "cmListFileLexer.in.l"
+#line 148 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Identifier;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 6:
+case 8:
+YY_RULE_SETUP
+#line 155 "cmListFileLexer.in.l"
+{
+ /* Handle ]]====]=======]*/
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ if(yyleng == lexer->bracket)
+ {
+ BEGIN(BRACKETEND);
+ }
+}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 165 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+ /* Erase the partial bracket from the token. */
+ lexer->token.length -= lexer->bracket;
+ lexer->token.text[lexer->token.length] = 0;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 10:
+YY_RULE_SETUP
+#line 174 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 179 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ BEGIN(BRACKET);
+}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 186 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ BEGIN(BRACKET);
+}
+ YY_BREAK
+case YY_STATE_EOF(BRACKET):
+case YY_STATE_EOF(BRACKETEND):
+#line 192 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_BadBracket;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 13:
YY_RULE_SETUP
-#line 117 "cmListFileLexer.in.l"
+#line 198 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 7:
+case 14:
YY_RULE_SETUP
-#line 124 "cmListFileLexer.in.l"
+#line 205 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 8:
+case 15:
YY_RULE_SETUP
-#line 131 "cmListFileLexer.in.l"
+#line 212 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
cmListFileLexerSetToken(lexer, "", 0);
@@ -964,69 +1114,69 @@ YY_RULE_SETUP
BEGIN(STRING);
}
YY_BREAK
-case 9:
+case 16:
YY_RULE_SETUP
-#line 138 "cmListFileLexer.in.l"
+#line 219 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
-case 10:
-/* rule 10 can match eol */
+case 17:
+/* rule 17 can match eol */
YY_RULE_SETUP
-#line 143 "cmListFileLexer.in.l"
+#line 224 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 11:
-/* rule 11 can match eol */
+case 18:
+/* rule 18 can match eol */
YY_RULE_SETUP
-#line 149 "cmListFileLexer.in.l"
+#line 230 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 12:
+case 19:
YY_RULE_SETUP
-#line 155 "cmListFileLexer.in.l"
+#line 236 "cmListFileLexer.in.l"
{
lexer->column += yyleng;
BEGIN(INITIAL);
return 1;
}
-case 13:
+case 20:
YY_RULE_SETUP
-#line 161 "cmListFileLexer.in.l"
+#line 242 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
case YY_STATE_EOF(STRING):
-#line 166 "cmListFileLexer.in.l"
+#line 247 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadString;
BEGIN(INITIAL);
return 1;
}
-case 14:
+case 21:
YY_RULE_SETUP
-#line 172 "cmListFileLexer.in.l"
+#line 253 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Space;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 15:
+case 22:
YY_RULE_SETUP
-#line 179 "cmListFileLexer.in.l"
+#line 260 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadCharacter;
cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -1034,18 +1184,19 @@ YY_RULE_SETUP
return 1;
}
case YY_STATE_EOF(INITIAL):
-#line 186 "cmListFileLexer.in.l"
+case YY_STATE_EOF(COMMENT):
+#line 267 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_None;
cmListFileLexerSetToken(lexer, 0, 0);
return 0;
}
-case 16:
+case 23:
YY_RULE_SETUP
-#line 192 "cmListFileLexer.in.l"
+#line 273 "cmListFileLexer.in.l"
ECHO;
YY_BREAK
-#line 1064 "cmListFileLexer.c"
+#line 1217 "cmListFileLexer.c"
case YY_END_OF_BUFFER:
{
@@ -1337,7 +1488,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 >= 45 )
+ if ( yy_current_state >= 77 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1366,11 +1517,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 >= 45 )
+ if ( yy_current_state >= 77 )
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 == 44);
+ yy_is_jam = (yy_current_state == 76);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2166,7 +2317,7 @@ void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 192 "cmListFileLexer.in.l"
+#line 273 "cmListFileLexer.in.l"
@@ -2243,7 +2394,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
{
if(lexer->file)
{
- return (int)fread(buffer, 1, bufferSize, lexer->file);
+ /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode
+ does not convert newlines on all platforms. Move any
+ trailing CR to the start of the buffer for the next read. */
+ size_t cr = lexer->cr;
+ size_t n;
+ buffer[0] = '\r';
+ n = fread(buffer+cr, 1, bufferSize-cr, lexer->file);
+ if(n)
+ {
+ char* o = buffer;
+ const char* i = buffer;
+ const char* e;
+ n += cr;
+ cr = (buffer[n-1] == '\r')? 1:0;
+ e = buffer + n - cr;
+ while(i != e)
+ {
+ if(i[0] == '\r' && i[1] == '\n')
+ {
+ ++i;
+ }
+ *o++ = *i++;
+ }
+ n = o - buffer;
+ }
+ else
+ {
+ n = cr;
+ cr = 0;
+ }
+ lexer->cr = cr;
+ return n;
}
else if(lexer->string_left)
{
@@ -2307,19 +2489,68 @@ cmListFileLexer* cmListFileLexer_New()
/*--------------------------------------------------------------------------*/
void cmListFileLexer_Delete(cmListFileLexer* lexer)
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
free(lexer);
}
/*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+{
+ unsigned char b[2];
+ if(fread(b, 1, 2, f) == 2)
+ {
+ if(b[0] == 0xEF && b[1] == 0xBB)
+ {
+ if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF)
+ {
+ return cmListFileLexer_BOM_UTF8;
+ }
+ }
+ else if(b[0] == 0xFE && b[1] == 0xFF)
+ {
+ /* UTF-16 BE */
+ return cmListFileLexer_BOM_UTF16BE;
+ }
+ else if(b[0] == 0 && b[1] == 0)
+ {
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF)
+ {
+ return cmListFileLexer_BOM_UTF32BE;
+ }
+ }
+ else if(b[0] == 0xFF && b[1] == 0xFE)
+ {
+ fpos_t p;
+ fgetpos(f, &p);
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0)
+ {
+ return cmListFileLexer_BOM_UTF32LE;
+ }
+ fsetpos(f, &p);
+ return cmListFileLexer_BOM_UTF16LE;
+ }
+ }
+ rewind(f);
+ return cmListFileLexer_BOM_None;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
+ cmListFileLexer_BOM* bom)
{
int result = 1;
cmListFileLexerDestroy(lexer);
if(name)
{
- lexer->file = fopen(name, "r");
- if(!lexer->file)
+ lexer->file = fopen(name, "rb");
+ if(lexer->file)
+ {
+ if(bom)
+ {
+ *bom = cmListFileLexer_ReadBOM(lexer->file);
+ }
+ }
+ else
{
result = 0;
}
@@ -2365,7 +2596,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
}
else
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
return 0;
}
}
@@ -2411,7 +2642,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
case cmListFileLexer_Token_ParenRight: return "right paren";
case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_ArgumentBracket: return "bracket argument";
+ case cmListFileLexer_Token_CommentBracket: return "bracket comment";
case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadBracket: return "unterminated bracket";
case cmListFileLexer_Token_BadString: return "unterminated string";
}
return "unknown token";
diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h
index cc78b5c..bd2868a 100644
--- a/Source/cmListFileLexer.h
+++ b/Source/cmListFileLexer.h
@@ -22,7 +22,10 @@ typedef enum cmListFileLexer_Type_e
cmListFileLexer_Token_ParenRight,
cmListFileLexer_Token_ArgumentUnquoted,
cmListFileLexer_Token_ArgumentQuoted,
+ cmListFileLexer_Token_ArgumentBracket,
+ cmListFileLexer_Token_CommentBracket,
cmListFileLexer_Token_BadCharacter,
+ cmListFileLexer_Token_BadBracket,
cmListFileLexer_Token_BadString
} cmListFileLexer_Type;
@@ -36,6 +39,17 @@ struct cmListFileLexer_Token_s
int column;
};
+enum cmListFileLexer_BOM_e
+{
+ cmListFileLexer_BOM_None,
+ cmListFileLexer_BOM_UTF8,
+ cmListFileLexer_BOM_UTF16BE,
+ cmListFileLexer_BOM_UTF16LE,
+ cmListFileLexer_BOM_UTF32BE,
+ cmListFileLexer_BOM_UTF32LE
+};
+typedef enum cmListFileLexer_BOM_e cmListFileLexer_BOM;
+
typedef struct cmListFileLexer_s cmListFileLexer;
#ifdef __cplusplus
@@ -44,7 +58,8 @@ extern "C"
#endif
cmListFileLexer* cmListFileLexer_New();
-int cmListFileLexer_SetFileName(cmListFileLexer*, const char*);
+int cmListFileLexer_SetFileName(cmListFileLexer*, const char*,
+ cmListFileLexer_BOM* bom);
int cmListFileLexer_SetString(cmListFileLexer*, const char*);
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer*);
long cmListFileLexer_GetCurrentLine(cmListFileLexer*);
diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l
index bd3c1eb..ecaf156 100644
--- a/Source/cmListFileLexer.in.l
+++ b/Source/cmListFileLexer.in.l
@@ -42,10 +42,13 @@ Modify cmListFileLexer.c:
struct cmListFileLexer_s
{
cmListFileLexer_Token token;
+ int bracket;
+ int comment;
int line;
int column;
int size;
FILE* file;
+ size_t cr;
char* string_buffer;
char* string_position;
int string_left;
@@ -74,22 +77,57 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
%option noyywrap
%pointer
%x STRING
+%x BRACKET
+%x BRACKETEND
+%x COMMENT
MAKEVAR \$\([A-Za-z0-9_]*\)
-UNQUOTED ([^ \t\r\n\(\)#\\\"]|\\.)
-LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
+UNQUOTED ([^ \t\r\n\(\)#\\\"[=]|\\.)
+LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\"
%%
-\n {
+<INITIAL,COMMENT>\n {
lexer->token.type = cmListFileLexer_Token_Newline;
cmListFileLexerSetToken(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
+ BEGIN(INITIAL);
return 1;
}
-#.* {
+#?\[=*\[\n? {
+ const char* bracket = yytext;
+ lexer->comment = yytext[0] == '#';
+ if(lexer->comment)
+ {
+ lexer->token.type = cmListFileLexer_Token_CommentBracket;
+ bracket += 1;
+ }
+ else
+ {
+ lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
+ }
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->bracket = (int)(strchr(bracket+1, '[') - bracket);
+ if(yytext[yyleng-1] == '\n')
+ {
+ ++lexer->line;
+ lexer->column = 1;
+ }
+ else
+ {
+ lexer->column += yyleng;
+ }
+ BEGIN(BRACKET);
+}
+
+# {
+ lexer->column += yyleng;
+ BEGIN(COMMENT);
+}
+
+<COMMENT>.* {
lexer->column += yyleng;
}
@@ -107,21 +145,64 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
return 1;
}
-[A-Za-z_][A-Za-z0-9_]+ {
+[A-Za-z_][A-Za-z0-9_]* {
lexer->token.type = cmListFileLexer_Token_Identifier;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-({UNQUOTED})({UNQUOTED})* {
+<BRACKET>\]=* {
+ /* Handle ]]====]=======]*/
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ if(yyleng == lexer->bracket)
+ {
+ BEGIN(BRACKETEND);
+ }
+}
+
+<BRACKETEND>\] {
+ lexer->column += yyleng;
+ /* Erase the partial bracket from the token. */
+ lexer->token.length -= lexer->bracket;
+ lexer->token.text[lexer->token.length] = 0;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+<BRACKET>([^]\n])+ {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+
+<BRACKET,BRACKETEND>\n {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ BEGIN(BRACKET);
+}
+
+<BRACKET,BRACKETEND>. {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ BEGIN(BRACKET);
+}
+
+<BRACKET,BRACKETEND><<EOF>> {
+ lexer->token.type = cmListFileLexer_Token_BadBracket;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+({UNQUOTED}|=|\[=*{UNQUOTED})({UNQUOTED}|[[=])* {
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-({MAKEVAR}|{UNQUOTED})({LEGACY})* {
+({MAKEVAR}|{UNQUOTED}|=|\[=*{LEGACY})({LEGACY}|[[=])* {
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
@@ -264,7 +345,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
{
if(lexer->file)
{
- return (int)fread(buffer, 1, bufferSize, lexer->file);
+ /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode
+ does not convert newlines on all platforms. Move any
+ trailing CR to the start of the buffer for the next read. */
+ size_t cr = lexer->cr;
+ size_t n;
+ buffer[0] = '\r';
+ n = fread(buffer+cr, 1, bufferSize-cr, lexer->file);
+ if(n)
+ {
+ char* o = buffer;
+ const char* i = buffer;
+ const char* e;
+ n += cr;
+ cr = (buffer[n-1] == '\r')? 1:0;
+ e = buffer + n - cr;
+ while(i != e)
+ {
+ if(i[0] == '\r' && i[1] == '\n')
+ {
+ ++i;
+ }
+ *o++ = *i++;
+ }
+ n = o - buffer;
+ }
+ else
+ {
+ n = cr;
+ cr = 0;
+ }
+ lexer->cr = cr;
+ return n;
}
else if(lexer->string_left)
{
@@ -328,19 +440,68 @@ cmListFileLexer* cmListFileLexer_New()
/*--------------------------------------------------------------------------*/
void cmListFileLexer_Delete(cmListFileLexer* lexer)
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
free(lexer);
}
/*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+{
+ unsigned char b[2];
+ if(fread(b, 1, 2, f) == 2)
+ {
+ if(b[0] == 0xEF && b[1] == 0xBB)
+ {
+ if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF)
+ {
+ return cmListFileLexer_BOM_UTF8;
+ }
+ }
+ else if(b[0] == 0xFE && b[1] == 0xFF)
+ {
+ /* UTF-16 BE */
+ return cmListFileLexer_BOM_UTF16BE;
+ }
+ else if(b[0] == 0 && b[1] == 0)
+ {
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF)
+ {
+ return cmListFileLexer_BOM_UTF32BE;
+ }
+ }
+ else if(b[0] == 0xFF && b[1] == 0xFE)
+ {
+ fpos_t p;
+ fgetpos(f, &p);
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0)
+ {
+ return cmListFileLexer_BOM_UTF32LE;
+ }
+ fsetpos(f, &p);
+ return cmListFileLexer_BOM_UTF16LE;
+ }
+ }
+ rewind(f);
+ return cmListFileLexer_BOM_None;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
+ cmListFileLexer_BOM* bom)
{
int result = 1;
cmListFileLexerDestroy(lexer);
if(name)
{
- lexer->file = fopen(name, "r");
- if(!lexer->file)
+ lexer->file = fopen(name, "rb");
+ if(lexer->file)
+ {
+ if(bom)
+ {
+ *bom = cmListFileLexer_ReadBOM(lexer->file);
+ }
+ }
+ else
{
result = 0;
}
@@ -386,7 +547,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
}
else
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
return 0;
}
}
@@ -432,7 +593,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
case cmListFileLexer_Token_ParenRight: return "right paren";
case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_ArgumentBracket: return "bracket argument";
+ case cmListFileLexer_Token_CommentBracket: return "bracket comment";
case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadBracket: return "unterminated bracket";
case cmListFileLexer_Token_BadString: return "unterminated string";
}
return "unknown token";
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 64de448..f21abc3 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -27,9 +27,6 @@
#include <ctype.h> // for isspace
-// Package GUID of Intel Visual Fortran plugin to VS IDE
-#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
-
static bool cmLVS6G_IsFAT(const char* dir);
class cmLocalVisualStudio7GeneratorInternals
@@ -1961,35 +1958,10 @@ cmLocalVisualStudio7Generator
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
-
- // Compute the version of the Intel plugin to the VS IDE.
- // If the key does not exist then use a default guess.
- std::string intelVersion;
- std::string vskey = gg->GetRegistryBase();
- vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
- cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
- cmSystemTools::KeyWOW64_32);
- unsigned int intelVersionNumber = ~0u;
- sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
- if(intelVersionNumber >= 11)
- {
- // Default to latest known project file version.
- intelVersion = "11.0";
- }
- else if(intelVersionNumber == 10)
- {
- // Version 10.x actually uses 9.10 in project files!
- intelVersion = "9.10";
- }
- else
- {
- // Version <= 9: use ProductVersion from registry.
- }
-
fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
<< "<VisualStudioProject\n"
<< "\tProjectCreator=\"Intel Fortran\"\n"
- << "\tVersion=\"" << intelVersion << "\"\n";
+ << "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
const char* keyword = target.GetProperty("VS_KEYWORD");
if(!keyword)
{
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a390e06..13c43fa 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2867,6 +2867,12 @@ bool cmMakefile::ExpandArguments(
outArgs.reserve(inArgs.size());
for(i = inArgs.begin(); i != inArgs.end(); ++i)
{
+ // No expansion in a bracket argument.
+ if(i->Delim == cmListFileArgument::Bracket)
+ {
+ outArgs.push_back(i->Value);
+ continue;
+ }
// Expand the variables in the argument.
value = i->Value;
this->ExpandVariablesInString(value, false, false, false,
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 6ede28b..ffab8e5 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -19,14 +19,13 @@ public:
cmPolicy(cmPolicies::PolicyID iD,
const char *idString,
const char *shortDescription,
- const char *longDescription,
unsigned int majorVersionIntroduced,
unsigned int minorVersionIntroduced,
unsigned int patchVersionIntroduced,
unsigned int tweakVersionIntroduced,
cmPolicies::PolicyStatus status)
{
- if (!idString || !shortDescription || ! longDescription)
+ if (!idString || !shortDescription)
{
cmSystemTools::Error("Attempt to define a policy without "
"all parameters being specified!");
@@ -35,7 +34,6 @@ public:
this->ID = iD;
this->IDString = idString;
this->ShortDescription = shortDescription;
- this->LongDescription = longDescription;
this->MajorVersionIntroduced = majorVersionIntroduced;
this->MinorVersionIntroduced = minorVersionIntroduced;
this->PatchVersionIntroduced = patchVersionIntroduced;
@@ -90,7 +88,6 @@ public:
cmPolicies::PolicyID ID;
std::string IDString;
std::string ShortDescription;
- std::string LongDescription;
unsigned int MajorVersionIntroduced;
unsigned int MinorVersionIntroduced;
unsigned int PatchVersionIntroduced;
@@ -104,561 +101,146 @@ cmPolicies::cmPolicies()
this->DefinePolicy(
CMP0000, "CMP0000",
"A minimum required CMake version must be specified.",
- "CMake requires that projects specify the version of CMake to which "
- "they have been written. "
- "This policy has been put in place so users trying to build the project "
- "may be told when they need to update their CMake. "
- "Specifying a version also helps the project build with CMake versions "
- "newer than that specified. "
- "Use the cmake_minimum_required command at the top of your main "
- " CMakeLists.txt file:\n"
- " cmake_minimum_required(VERSION <major>.<minor>)\n"
- "where \"<major>.<minor>\" is the version of CMake you want to support "
- "(such as \"2.6\"). "
- "The command will ensure that at least the given version of CMake is "
- "running and help newer versions be compatible with the project. "
- "See documentation of cmake_minimum_required for details.\n"
- "Note that the command invocation must appear in the CMakeLists.txt "
- "file itself; a call in an included file is not sufficient. "
- "However, the cmake_policy command may be called to set policy "
- "CMP0000 to OLD or NEW behavior explicitly. "
- "The OLD behavior is to silently ignore the missing invocation. "
- "The NEW behavior is to issue an error instead of a warning. "
- "An included file may set CMP0000 explicitly to affect how this "
- "policy is enforced for the main CMakeLists.txt file.",
2,6,0,0, cmPolicies::WARN
);
this->DefinePolicy(
CMP0001, "CMP0001",
"CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.",
- "The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present "
- "it to the user. "
- "The NEW behavior is to ignore CMAKE_BACKWARDS_COMPATIBILITY "
- "completely.\n"
- "In CMake 2.4 and below the variable CMAKE_BACKWARDS_COMPATIBILITY was "
- "used to request compatibility with earlier versions of CMake. "
- "In CMake 2.6 and above all compatibility issues are handled by policies "
- "and the cmake_policy command. "
- "However, CMake must still check CMAKE_BACKWARDS_COMPATIBILITY for "
- "projects written for CMake 2.4 and below.",
2,6,0,0, cmPolicies::WARN
);
this->DefinePolicy(
CMP0002, "CMP0002",
"Logical target names must be globally unique.",
- "Targets names created with "
- "add_executable, add_library, or add_custom_target "
- "are logical build target names. "
- "Logical target names must be globally unique because:\n"
- " - Unique names may be referenced unambiguously both in CMake\n"
- " code and on make tool command lines.\n"
- " - Logical names are used by Xcode and VS IDE generators\n"
- " to produce meaningful project names for the targets.\n"
- "The logical name of executable and library targets does not "
- "have to correspond to the physical file names built. "
- "Consider using the OUTPUT_NAME target property to create two "
- "targets with the same physical name while keeping logical "
- "names distinct. "
- "Custom targets must simply have globally unique names (unless one "
- "uses the global property ALLOW_DUPLICATE_CUSTOM_TARGETS with a "
- "Makefiles generator).",
2,6,0,0, cmPolicies::WARN
);
this->DefinePolicy(
CMP0003, "CMP0003",
"Libraries linked via full path no longer produce linker search paths.",
- "This policy affects how libraries whose full paths are NOT known "
- "are found at link time, but was created due to a change in how CMake "
- "deals with libraries whose full paths are known. "
- "Consider the code\n"
- " target_link_libraries(myexe /path/to/libA.so)\n"
- "CMake 2.4 and below implemented linking to libraries whose full paths "
- "are known by splitting them on the link line into separate components "
- "consisting of the linker search path and the library name. "
- "The example code might have produced something like\n"
- " ... -L/path/to -lA ...\n"
- "in order to link to library A. "
- "An analysis was performed to order multiple link directories such that "
- "the linker would find library A in the desired location, but there "
- "are cases in which this does not work. "
- "CMake versions 2.6 and above use the more reliable approach of passing "
- "the full path to libraries directly to the linker in most cases. "
- "The example code now produces something like\n"
- " ... /path/to/libA.so ....\n"
- "Unfortunately this change can break code like\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "where \"B\" is meant to find \"/path/to/libB.so\". "
- "This code is wrong because the user is asking the linker to find "
- "library B but has not provided a linker search path (which may be "
- "added with the link_directories command). "
- "However, with the old linking implementation the code would work "
- "accidentally because the linker search path added for library A "
- "allowed library B to be found."
- "\n"
- "In order to support projects depending on linker search paths "
- "added by linking to libraries with known full paths, the OLD "
- "behavior for this policy will add the linker search paths even "
- "though they are not needed for their own libraries. "
- "When this policy is set to OLD, CMake will produce a link line such as\n"
- " ... -L/path/to /path/to/libA.so -lB ...\n"
- "which will allow library B to be found as it was previously. "
- "When this policy is set to NEW, CMake will produce a link line such as\n"
- " ... /path/to/libA.so -lB ...\n"
- "which more accurately matches what the project specified."
- "\n"
- "The setting for this policy used when generating the link line is that "
- "in effect when the target is created by an add_executable or "
- "add_library command. For the example described above, the code\n"
- " cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "will work and suppress the warning for this policy. "
- "It may also be updated to work with the corrected linking approach:\n"
- " cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)\n"
- " link_directories(/path/to) # needed to find library B\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "Even better, library B may be specified with a full path:\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)\n"
- "When all items on the link line have known paths CMake does not check "
- "this policy so it has no effect.\n"
- "Note that the warning for this policy will be issued for at most "
- "one target. This avoids flooding users with messages for every "
- "target when setting the policy once will probably fix all targets.",
2,6,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0004, "CMP0004",
"Libraries linked may not have leading or trailing whitespace.",
- "CMake versions 2.4 and below silently removed leading and trailing "
- "whitespace from libraries linked with code like\n"
- " target_link_libraries(myexe \" A \")\n"
- "This could lead to subtle errors in user projects.\n"
- "The OLD behavior for this policy is to silently remove leading and "
- "trailing whitespace. "
- "The NEW behavior for this policy is to diagnose the existence of "
- "such whitespace as an error. "
- "The setting for this policy used when checking the library names is "
- "that in effect when the target is created by an add_executable or "
- "add_library command.",
2,6,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0005, "CMP0005",
"Preprocessor definition values are now escaped automatically.",
- "This policy determines whether or not CMake should generate escaped "
- "preprocessor definition values added via add_definitions. "
- "CMake versions 2.4 and below assumed that only trivial values would "
- "be given for macros in add_definitions calls. "
- "It did not attempt to escape non-trivial values such as string "
- "literals in generated build rules. "
- "CMake versions 2.6 and above support escaping of most values, but "
- "cannot assume the user has not added escapes already in an attempt to "
- "work around limitations in earlier versions.\n"
- "The OLD behavior for this policy is to place definition values given "
- "to add_definitions directly in the generated build rules without "
- "attempting to escape anything. "
- "The NEW behavior for this policy is to generate correct escapes "
- "for all native build tools automatically. "
- "See documentation of the COMPILE_DEFINITIONS target property for "
- "limitations of the escaping implementation.",
2,6,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0006, "CMP0006",
"Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.",
- "This policy determines whether the install(TARGETS) command must be "
- "given a BUNDLE DESTINATION when asked to install a target with the "
- "MACOSX_BUNDLE property set. "
- "CMake 2.4 and below did not distinguish application bundles from "
- "normal executables when installing targets. "
- "CMake 2.6 provides a BUNDLE option to the install(TARGETS) command "
- "that specifies rules specific to application bundles on the Mac. "
- "Projects should use this option when installing a target with the "
- "MACOSX_BUNDLE property set.\n"
- "The OLD behavior for this policy is to fall back to the RUNTIME "
- "DESTINATION if a BUNDLE DESTINATION is not given. "
- "The NEW behavior for this policy is to produce an error if a bundle "
- "target is installed without a BUNDLE DESTINATION.",
2,6,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0007, "CMP0007",
"list command no longer ignores empty elements.",
- "This policy determines whether the list command will "
- "ignore empty elements in the list. "
- "CMake 2.4 and below list commands ignored all empty elements"
- " in the list. For example, a;b;;c would have length 3 and not 4. "
- "The OLD behavior for this policy is to ignore empty list elements. "
- "The NEW behavior for this policy is to correctly count empty "
- "elements in a list. ",
2,6,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0008, "CMP0008",
"Libraries linked by full-path must have a valid library file name.",
- "In CMake 2.4 and below it is possible to write code like\n"
- " target_link_libraries(myexe /full/path/to/somelib)\n"
- "where \"somelib\" is supposed to be a valid library file name "
- "such as \"libsomelib.a\" or \"somelib.lib\". "
- "For Makefile generators this produces an error at build time "
- "because the dependency on the full path cannot be found. "
- "For VS IDE and Xcode generators this used to work by accident because "
- "CMake would always split off the library directory and ask the "
- "linker to search for the library by name (-lsomelib or somelib.lib). "
- "Despite the failure with Makefiles, some projects have code like this "
- "and build only with VS and/or Xcode. "
- "This version of CMake prefers to pass the full path directly to the "
- "native build tool, which will fail in this case because it does "
- "not name a valid library file."
- "\n"
- "This policy determines what to do with full paths that do not appear "
- "to name a valid library file. "
- "The OLD behavior for this policy is to split the library name from the "
- "path and ask the linker to search for it. "
- "The NEW behavior for this policy is to trust the given path and "
- "pass it directly to the native build tool unchanged.",
2,6,1,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0009, "CMP0009",
"FILE GLOB_RECURSE calls should not follow symlinks by default.",
- "In CMake 2.6.1 and below, FILE GLOB_RECURSE calls would follow "
- "through symlinks, sometimes coming up with unexpectedly large "
- "result sets because of symlinks to top level directories that "
- "contain hundreds of thousands of files."
- "\n"
- "This policy determines whether or not to follow symlinks "
- "encountered during a FILE GLOB_RECURSE call. "
- "The OLD behavior for this policy is to follow the symlinks. "
- "The NEW behavior for this policy is not to follow the symlinks "
- "by default, but only if FOLLOW_SYMLINKS is given as an additional "
- "argument to the FILE command.",
2,6,2,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0010, "CMP0010",
"Bad variable reference syntax is an error.",
- "In CMake 2.6.2 and below, incorrect variable reference syntax such as "
- "a missing close-brace (\"${FOO\") was reported but did not stop "
- "processing of CMake code. "
- "This policy determines whether a bad variable reference is an error. "
- "The OLD behavior for this policy is to warn about the error, leave "
- "the string untouched, and continue. "
- "The NEW behavior for this policy is to report an error.",
2,6,3,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0011, "CMP0011",
"Included scripts do automatic cmake_policy PUSH and POP.",
- "In CMake 2.6.2 and below, CMake Policy settings in scripts loaded by "
- "the include() and find_package() commands would affect the includer. "
- "Explicit invocations of cmake_policy(PUSH) and cmake_policy(POP) were "
- "required to isolate policy changes and protect the includer. "
- "While some scripts intend to affect the policies of their includer, "
- "most do not. "
- "In CMake 2.6.3 and above, include() and find_package() by default PUSH "
- "and POP an entry on the policy stack around an included script, "
- "but provide a NO_POLICY_SCOPE option to disable it. "
- "This policy determines whether or not to imply NO_POLICY_SCOPE for "
- "compatibility. "
- "The OLD behavior for this policy is to imply NO_POLICY_SCOPE for "
- "include() and find_package() commands. "
- "The NEW behavior for this policy is to allow the commands to do their "
- "default cmake_policy PUSH and POP.",
2,6,3,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0012, "CMP0012",
"if() recognizes numbers and boolean constants.",
- "In CMake versions 2.6.4 and lower the if() command implicitly "
- "dereferenced arguments corresponding to variables, even those named "
- "like numbers or boolean constants, except for 0 and 1. "
- "Numbers and boolean constants such as true, false, yes, no, "
- "on, off, y, n, notfound, ignore (all case insensitive) were recognized "
- "in some cases but not all. "
- "For example, the code \"if(TRUE)\" might have evaluated as false. "
- "Numbers such as 2 were recognized only in "
- "boolean expressions like \"if(NOT 2)\" (leading to false) "
- "but not as a single-argument like \"if(2)\" (also leading to false). "
- "Later versions of CMake prefer to treat numbers and boolean constants "
- "literally, so they should not be used as variable names."
- "\n"
- "The OLD behavior for this policy is to implicitly dereference variables "
- "named like numbers and boolean constants. "
- "The NEW behavior for this policy is to recognize numbers and "
- "boolean constants without dereferencing variables with such names.",
2,8,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0013, "CMP0013",
"Duplicate binary directories are not allowed.",
- "CMake 2.6.3 and below silently permitted add_subdirectory() calls "
- "to create the same binary directory multiple times. "
- "During build system generation files would be written and then "
- "overwritten in the build tree and could lead to strange behavior. "
- "CMake 2.6.4 and above explicitly detect duplicate binary directories. "
- "CMake 2.6.4 always considers this case an error. "
- "In CMake 2.8.0 and above this policy determines whether or not "
- "the case is an error. "
- "The OLD behavior for this policy is to allow duplicate binary "
- "directories. "
- "The NEW behavior for this policy is to disallow duplicate binary "
- "directories with an error.",
2,8,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0014, "CMP0014",
"Input directories must have CMakeLists.txt.",
- "CMake versions before 2.8 silently ignored missing CMakeLists.txt "
- "files in directories referenced by add_subdirectory() or subdirs(), "
- "treating them as if present but empty. "
- "In CMake 2.8.0 and above this policy determines whether or not "
- "the case is an error. "
- "The OLD behavior for this policy is to silently ignore the problem. "
- "The NEW behavior for this policy is to report an error.",
2,8,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0015, "CMP0015",
"link_directories() treats paths relative to the source dir.",
- "In CMake 2.8.0 and lower the link_directories() command passed relative "
- "paths unchanged to the linker. "
- "In CMake 2.8.1 and above the link_directories() command prefers to "
- "interpret relative paths with respect to CMAKE_CURRENT_SOURCE_DIR, "
- "which is consistent with include_directories() and other commands. "
- "The OLD behavior for this policy is to use relative paths verbatim in "
- "the linker command. "
- "The NEW behavior for this policy is to convert relative paths to "
- "absolute paths by appending the relative path to "
- "CMAKE_CURRENT_SOURCE_DIR.",
2,8,1,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0016, "CMP0016",
"target_link_libraries() reports error if its only argument "
"is not a target.",
- "In CMake 2.8.2 and lower the target_link_libraries() command silently "
- "ignored if it was called with only one argument, and this argument "
- "wasn't a valid target. "
- "In CMake 2.8.3 and above it reports an error in this case.",
2,8,3,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0017, "CMP0017",
"Prefer files from the CMake module directory when including from there.",
- "Starting with CMake 2.8.4, if a cmake-module shipped with CMake (i.e. "
- "located in the CMake module directory) calls include() or "
- "find_package(), the files located in the CMake module directory are "
- "preferred over the files in CMAKE_MODULE_PATH. "
- "This makes sure that the modules belonging to "
- "CMake always get those files included which they expect, and against "
- "which they were developed and tested. "
- "In all other cases, the files found in "
- "CMAKE_MODULE_PATH still take precedence over the ones in "
- "the CMake module directory. "
- "The OLD behaviour is to always prefer files from CMAKE_MODULE_PATH over "
- "files from the CMake modules directory.",
2,8,4,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0018, "CMP0018",
"Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.",
- "CMake 2.8.8 and lower compiled sources in SHARED and MODULE libraries "
- "using the value of the undocumented CMAKE_SHARED_LIBRARY_<Lang>_FLAGS "
- "platform variable. The variable contained platform-specific flags "
- "needed to compile objects for shared libraries. Typically it included "
- "a flag such as -fPIC for position independent code but also included "
- "other flags needed on certain platforms. CMake 2.8.9 and higher "
- "prefer instead to use the POSITION_INDEPENDENT_CODE target property to "
- "determine what targets should be position independent, and new "
- "undocumented platform variables to select flags while ignoring "
- "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS completely."
- "\n"
- "The default for either approach produces identical compilation flags, "
- "but if a project modifies CMAKE_SHARED_LIBRARY_<Lang>_FLAGS from its "
- "original value this policy determines which approach to use."
- "\n"
- "The OLD behavior for this policy is to ignore the "
- "POSITION_INDEPENDENT_CODE property for all targets and use the modified "
- "value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS for SHARED and MODULE "
- "libraries."
- "\n"
- "The NEW behavior for this policy is to ignore "
- "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
- "honor the POSITION_INDEPENDENT_CODE target property.",
2,8,9,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0019, "CMP0019",
"Do not re-expand variables in include and link information.",
- "CMake 2.8.10 and lower re-evaluated values given to the "
- "include_directories, link_directories, and link_libraries "
- "commands to expand any leftover variable references at the "
- "end of the configuration step. "
- "This was for strict compatibility with VERY early CMake versions "
- "because all variable references are now normally evaluated during "
- "CMake language processing. "
- "CMake 2.8.11 and higher prefer to skip the extra evaluation."
- "\n"
- "The OLD behavior for this policy is to re-evaluate the values "
- "for strict compatibility. "
- "The NEW behavior for this policy is to leave the values untouched.",
2,8,11,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0020, "CMP0020",
"Automatically link Qt executables to qtmain target on Windows.",
- "CMake 2.8.10 and lower required users of Qt to always specify a link "
- "dependency to the qtmain.lib static library manually on Windows. CMake "
- "2.8.11 gained the ability to evaluate generator expressions while "
- "determining the link dependencies from IMPORTED targets. This allows "
- "CMake itself to automatically link executables which link to Qt to the "
- "qtmain.lib library when using IMPORTED Qt targets. For applications "
- "already linking to qtmain.lib, this should have little impact. For "
- "applications which supply their own alternative WinMain implementation "
- "and for applications which use the QAxServer library, this automatic "
- "linking will need to be disabled as per the documentation."
- "\n"
- "The OLD behavior for this policy is not to link executables to "
- "qtmain.lib automatically when they link to the QtCore IMPORTED"
- "target. "
- "The NEW behavior for this policy is to link executables to "
- "qtmain.lib automatically when they link to QtCore IMPORTED target.",
2,8,11,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0021, "CMP0021",
"Fatal error on relative paths in INCLUDE_DIRECTORIES target property.",
- "CMake 2.8.10.2 and lower allowed the INCLUDE_DIRECTORIES target "
- "property to contain relative paths. The base path for such relative "
- "entries is not well defined. CMake 2.8.12 issues a FATAL_ERROR if the "
- "INCLUDE_DIRECTORIES property contains a relative path."
- "\n"
- "The OLD behavior for this policy is not to warn about relative paths in "
- "the INCLUDE_DIRECTORIES target property. "
- "The NEW behavior for this policy is to issue a FATAL_ERROR if "
- "INCLUDE_DIRECTORIES contains a relative path.",
2,8,12,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0022, "CMP0022",
"INTERFACE_LINK_LIBRARIES defines the link interface.",
- "CMake 2.8.11 constructed the 'link interface' of a target from "
- "properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?. "
- "The modern way to specify config-sensitive content is to use generator "
- "expressions and the IMPORTED_ prefix makes uniform processing of the "
- "link interface with generator expressions impossible. The "
- "INTERFACE_LINK_LIBRARIES target property was introduced as a "
- "replacement in CMake 2.8.12. This new property is named consistently "
- "with the INTERFACE_COMPILE_DEFINITIONS, INTERFACE_INCLUDE_DIRECTORIES "
- "and INTERFACE_COMPILE_OPTIONS properties. For in-build targets, CMake "
- "will use the INTERFACE_LINK_LIBRARIES property as the source of the "
- "link interface only if policy CMP0022 is NEW. "
- "When exporting a target which has this policy set to NEW, only the "
- "INTERFACE_LINK_LIBRARIES property will be processed and generated for "
- "the IMPORTED target by default. A new option to the install(EXPORT) "
- "and export commands allows export of the old-style properties for "
- "compatibility with downstream users of CMake versions older than "
- "2.8.12. "
- "The target_link_libraries command will no longer populate the "
- "properties matching LINK_INTERFACE_LIBRARIES(_<CONFIG>)? if this policy "
- "is NEW."
- "\n"
- "The OLD behavior for this policy is to ignore the "
- "INTERFACE_LINK_LIBRARIES property for in-build targets. "
- "The NEW behavior for this policy is to use the INTERFACE_LINK_LIBRARIES "
- "property for in-build targets, and ignore the old properties matching "
- "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
2,8,12,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0023, "CMP0023",
"Plain and keyword target_link_libraries signatures cannot be mixed.",
- "CMake 2.8.12 introduced the target_link_libraries signature using "
- "the PUBLIC, PRIVATE, and INTERFACE keywords to generalize the "
- "LINK_PUBLIC and LINK_PRIVATE keywords introduced in CMake 2.8.7. "
- "Use of signatures with any of these keywords sets the link interface "
- "of a target explicitly, even if empty. "
- "This produces confusing behavior when used in combination with the "
- "historical behavior of the plain target_link_libraries signature. "
- "For example, consider the code:\n"
- " target_link_libraries(mylib A)\n"
- " target_link_libraries(mylib PRIVATE B)\n"
- "After the first line the link interface has not been set explicitly "
- "so CMake would use the link implementation, A, as the link interface. "
- "However, the second line sets the link interface to empty. "
- "In order to avoid this subtle behavior CMake now prefers to disallow "
- "mixing the plain and keyword signatures of target_link_libraries for "
- "a single target."
- "\n"
- "The OLD behavior for this policy is to allow keyword and plain "
- "target_link_libraries signatures to be mixed. "
- "The NEW behavior for this policy is to not to allow mixing of the "
- "keyword and plain signatures.",
2,8,12,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0024, "CMP0024",
"Disallow include export result.",
- "CMake 2.8.12 and lower allowed use of the include() command with the "
- "result of the export() command. This relies on the assumption that "
- "the export() command has an immediate effect at configure-time during a "
- "cmake run. Certain properties of targets are not fully determined "
- "until later at generate-time, such as the link language and complete "
- "list of link libraries. Future refactoring will change the effect of "
- "the export() command to be executed at generate-time. Use ALIAS "
- "targets instead in cases where the goal is to refer to targets by "
- "another name"
- "\n"
- "The OLD behavior for this policy is to allow including the result "
- "of an export() command. "
- "The NEW behavior for this policy is to not to allow including the "
- "result of an export() command.",
- 2,8,13,0, cmPolicies::WARN);
+ 3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0025, "CMP0025",
"Compiler id for Apple Clang is now AppleClang.",
- "CMake >= 2.8.13 recognize that Apple Clang is a different compiler "
- "than upstream Clang and that they have different version numbers. "
- "CMake now prefers to present this to projects by setting "
- "CMAKE_<LANG>_COMPILER_ID to \"AppleClang\" instead of \"Clang\". "
- "However, existing projects may assume the compiler id for Apple Clang "
- "is just \"Clang\" as it was in CMake < 2.8.13. "
- "Therefore this policy determines for Apple Clang which compiler id "
- "to report in CMAKE_<LANG>_COMPILER_ID after <LANG> is enabled by "
- "the project() or enable_language() command."
- "\n"
- "The OLD behavior for this policy is to use compiler id \"Clang\". "
- "The NEW behavior for this policy is to use compiler id \"AppleClang\".",
- 2,8,13,0, cmPolicies::WARN);
+ 3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0026, "CMP0026",
"Disallow use of the LOCATION target property.",
- "CMake 2.8.12 and lower allowed reading the LOCATION target property to "
- "determine the eventual location of build targets. This relies on the "
- "assumption that all necessary information is available at "
- "configure-time to determine the final location and filename of the "
- "target. However, this property is not fully determined until later at "
- "generate-time. At generate time, the $<TARGET_FILE> generator "
- "expression can be used to determine the eventual LOCATION of a target "
- "output."
- "\n"
- "Code which reads the LOCATION target property can be ported to use the "
- "$<TARGET_FILE> generator expression together with the file(GENERATE) "
- "subcommand to generate a file containing the target location."
- "\n"
- "The OLD behavior for this policy is to allow reading the LOCATION "
- "property from build-targets. "
- "The NEW behavior for this policy is to not to allow reading the "
- "LOCATION property from build-targets.",
- 2,8,13,0, cmPolicies::WARN);
+ 3,0,0,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0027, "CMP0027",
+ "Conditionally linked imported targets with missing include directories.",
+ 3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
@@ -675,7 +257,6 @@ cmPolicies::~cmPolicies()
void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD,
const char *idString,
const char *shortDescription,
- const char *longDescription,
unsigned int majorVersionIntroduced,
unsigned int minorVersionIntroduced,
unsigned int patchVersionIntroduced,
@@ -692,7 +273,6 @@ void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD,
this->Policies[iD] = new cmPolicy(iD, idString,
shortDescription,
- longDescription,
majorVersionIntroduced,
minorVersionIntroduced,
patchVersionIntroduced,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a9d1b49..39c2afb 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -77,6 +77,8 @@ public:
CMP0024, ///< Disallow including export() result.
CMP0025, ///< Compiler id for Apple Clang is now AppleClang
CMP0026, ///< Disallow use of the LOCATION target property.
+ CMP0027, ///< Conditionally linked imported targets with missing include
+ /// directories.
/** \brief Always the last entry.
*
@@ -97,7 +99,6 @@ public:
void DefinePolicy(cmPolicies::PolicyID id,
const char *stringID,
const char *shortDescription,
- const char *longDescription,
unsigned int majorVersionIntroduced,
unsigned int minorVersionIntroduced,
unsigned int patchVersionIntroduced,
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 72c42d6..18a197b 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -12,6 +12,7 @@
#include "cmRST.h"
#include "cmSystemTools.h"
+#include "cmVersion.h"
#include <ctype.h>
@@ -41,6 +42,7 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot):
"((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))"
"([^A-Za-z0-9_]|$)")
{
+ this->Replace["|release|"] = cmVersion::GetCMakeVersion();
}
//----------------------------------------------------------------------------
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index cbd4632..8320ecf 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -115,19 +115,6 @@ bool cmSystemTools::s_FatalErrorOccured = false;
bool cmSystemTools::s_DisableMessages = false;
bool cmSystemTools::s_ForceUnixPaths = false;
-std::string cmSystemTools::s_Windows9xComspecSubstitute = "command.com";
-void cmSystemTools::SetWindows9xComspecSubstitute(const char* str)
-{
- if ( str )
- {
- cmSystemTools::s_Windows9xComspecSubstitute = str;
- }
-}
-const char* cmSystemTools::GetWindows9xComspecSubstitute()
-{
- return cmSystemTools::s_Windows9xComspecSubstitute.c_str();
-}
-
void (*cmSystemTools::s_ErrorCallback)(const char*, const char*,
bool&, void*);
void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*);
@@ -787,351 +774,6 @@ bool cmSystemTools::RunSingleCommand(
return cmSystemTools::RunSingleCommand(args, output,retVal,
dir, outputflag, timeout);
}
-bool cmSystemTools::RunCommand(const char* command,
- std::string& output,
- const char* dir,
- bool verbose,
- int timeout)
-{
- int dummy;
- return cmSystemTools::RunCommand(command, output, dummy,
- dir, verbose, timeout);
-}
-
-#if defined(WIN32) && !defined(__CYGWIN__)
-#include "cmWin32ProcessExecution.h"
-// use this for shell commands like echo and dir
-bool RunCommandViaWin32(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose,
- int timeout)
-{
-#if defined(__BORLANDC__)
- return
- cmWin32ProcessExecution::
- BorlandRunCommand(command, dir, output,
- retVal,
- verbose, timeout,
- cmSystemTools::GetRunCommandHideConsole());
-#else // Visual studio
- ::SetLastError(ERROR_SUCCESS);
- if ( ! command )
- {
- cmSystemTools::Error("No command specified");
- return false;
- }
- cmWin32ProcessExecution resProc;
- if(cmSystemTools::GetRunCommandHideConsole())
- {
- resProc.SetHideWindows(true);
- }
-
- if ( cmSystemTools::GetWindows9xComspecSubstitute() )
- {
- resProc.SetConsoleSpawn(cmSystemTools::GetWindows9xComspecSubstitute() );
- }
- if ( !resProc.StartProcess(command, dir, verbose) )
- {
- output = resProc.GetOutput();
- if(verbose)
- {
- cmSystemTools::Stdout(output.c_str());
- }
- return false;
- }
- resProc.Wait(timeout);
- output = resProc.GetOutput();
- retVal = resProc.GetExitValue();
- return true;
-#endif
-}
-
-// use this for shell commands like echo and dir
-bool RunCommandViaSystem(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose)
-{
- std::cout << "@@ " << command << std::endl;
-
- std::string commandInDir;
- if(dir)
- {
- commandInDir = "cd ";
- commandInDir += cmSystemTools::ConvertToOutputPath(dir);
- commandInDir += " && ";
- commandInDir += command;
- }
- else
- {
- commandInDir = command;
- }
- command = commandInDir.c_str();
- std::string commandToFile = command;
- commandToFile += " > ";
- std::string tempFile;
- tempFile += _tempnam(0, "cmake");
-
- commandToFile += tempFile;
- retVal = system(commandToFile.c_str());
- std::ifstream fin(tempFile.c_str());
- if(!fin)
- {
- if(verbose)
- {
- std::string errormsg = "RunCommand produced no output: command: \"";
- errormsg += command;
- errormsg += "\"";
- errormsg += "\nOutput file: ";
- errormsg += tempFile;
- cmSystemTools::Error(errormsg.c_str());
- }
- fin.close();
- cmSystemTools::RemoveFile(tempFile.c_str());
- return false;
- }
- bool multiLine = false;
- std::string line;
- while(cmSystemTools::GetLineFromStream(fin, line))
- {
- output += line;
- if(multiLine)
- {
- output += "\n";
- }
- multiLine = true;
- }
- fin.close();
- cmSystemTools::RemoveFile(tempFile.c_str());
- return true;
-}
-
-#else // We have popen
-
-// BeOS seems to return from a successful pclose() before the process has
-// legitimately exited, or at least before SIGCHLD is thrown...the signal may
-// come quite some time after pclose returns! This causes havoc with later
-// parts of CMake that expect to catch the signal from other child processes,
-// so we explicitly wait to catch it here. This should be safe to do with
-// popen() so long as we don't actually collect the zombie process ourselves.
-#ifdef __BEOS__
-#include <signal.h>
-#undef SIGBUS // this is the same as SIGSEGV on BeOS and causes issues below.
-static volatile bool beos_seen_signal = false;
-static void beos_popen_workaround(int sig)
-{
- beos_seen_signal = true;
-}
-#endif
-
-bool RunCommandViaPopen(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose,
- int /*timeout*/)
-{
- // if only popen worked on windows.....
- std::string commandInDir;
- if(dir)
- {
- commandInDir = "cd \"";
- commandInDir += dir;
- commandInDir += "\" && ";
- commandInDir += command;
- }
- else
- {
- commandInDir = command;
- }
-#ifndef __VMS
- commandInDir += " 2>&1";
-#endif
- command = commandInDir.c_str();
- const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- if(verbose)
- {
- cmSystemTools::Stdout("running ");
- cmSystemTools::Stdout(command);
- cmSystemTools::Stdout("\n");
- }
- fflush(stdout);
- fflush(stderr);
-
-#ifdef __BEOS__
- beos_seen_signal = false;
- signal(SIGCHLD, beos_popen_workaround);
-#endif
-
- FILE* cpipe = popen(command, "r");
- if(!cpipe)
- {
-#ifdef __BEOS__
- signal(SIGCHLD, SIG_DFL);
-#endif
- return false;
- }
- if (!fgets(buffer, BUFFER_SIZE, cpipe))
- {
- buffer[0] = 0;
- }
- while(!feof(cpipe))
- {
- if(verbose)
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- if(!fgets(buffer, BUFFER_SIZE, cpipe))
- {
- buffer[0] = 0;
- }
- }
-
- retVal = pclose(cpipe);
-
-#ifdef __BEOS__
- for (int i = 0; (!beos_seen_signal) && (i < 3); i++)
- {
- ::sleep(1); // signals should interrupt this...
- }
-
- if (!beos_seen_signal)
- {
- signal(SIGCHLD, SIG_DFL); // oh well, didn't happen. Go on anyhow.
- }
-#endif
-
- if (WIFEXITED(retVal))
- {
- retVal = WEXITSTATUS(retVal);
- return true;
- }
- if (WIFSIGNALED(retVal))
- {
- retVal = WTERMSIG(retVal);
- cmOStringStream error;
- error << "\nProcess terminated due to ";
- switch (retVal)
- {
-#ifdef SIGKILL
- case SIGKILL:
- error << "SIGKILL";
- break;
-#endif
-#ifdef SIGFPE
- case SIGFPE:
- error << "SIGFPE";
- break;
-#endif
-#ifndef __HAIKU__
-#ifdef SIGBUS
- case SIGBUS:
- error << "SIGBUS";
- break;
-#endif
-#endif
-#ifdef SIGSEGV
- case SIGSEGV:
- error << "SIGSEGV";
- break;
-#endif
- default:
- error << "signal " << retVal;
- break;
- }
- output += error.str();
- }
- return false;
-}
-
-#endif // endif WIN32 not CYGWIN
-
-
-// run a command unix uses popen (easy)
-// windows uses system and ShortPath
-bool cmSystemTools::RunCommand(const char* command,
- std::string& output,
- int &retVal,
- const char* dir,
- bool verbose,
- int timeout)
-{
- if(s_DisableRunCommandOutput)
- {
- verbose = false;
- }
-
-#if defined(WIN32) && !defined(__CYGWIN__)
- // if the command does not start with a quote, then
- // try to find the program, and if the program can not be
- // found use system to run the command as it must be a built in
- // shell command like echo or dir
- int count = 0;
- if(command[0] == '\"')
- {
- // count the number of quotes
- for(const char* s = command; *s != 0; ++s)
- {
- if(*s == '\"')
- {
- count++;
- if(count > 2)
- {
- break;
- }
- }
- }
- // if there are more than two double quotes use
- // GetShortPathName, the cmd.exe program in windows which
- // is used by system fails to execute if there are more than
- // one set of quotes in the arguments
- if(count > 2)
- {
- cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
- if(quoted.find(command))
- {
- std::string shortCmd;
- std::string cmd = quoted.match(1);
- std::string args = quoted.match(2);
- if(! cmSystemTools::FileExists(cmd.c_str()) )
- {
- shortCmd = cmd;
- }
- else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
- {
- cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
- return false;
- }
- shortCmd += " ";
- shortCmd += args;
-
- //return RunCommandViaSystem(shortCmd.c_str(), dir,
- // output, retVal, verbose);
- //return WindowsRunCommand(shortCmd.c_str(), dir,
- //output, retVal, verbose);
- return RunCommandViaWin32(shortCmd.c_str(), dir,
- output, retVal, verbose, timeout);
- }
- else
- {
- cmSystemTools::Error("Could not parse command line with quotes ",
- command);
- }
- }
- }
- // if there is only one set of quotes or no quotes then just run the command
- //return RunCommandViaSystem(command, dir, output, retVal, verbose);
- //return WindowsRunCommand(command, dir, output, retVal, verbose);
- return ::RunCommandViaWin32(command, dir, output, retVal, verbose, timeout);
-#else
- return ::RunCommandViaPopen(command, dir, output, retVal, verbose, timeout);
-#endif
-}
bool cmSystemTools::DoesFileExistWithExtensions(
const char* name,
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index cbc1140..07235da 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -191,23 +191,6 @@ public:
static std::string ComputeStringMD5(const char* input);
/**
- * Run an executable command and put the stdout in output.
- * A temporary file is created in the binaryDir for storing the
- * output because windows does not have popen.
- *
- * If verbose is false, no user-viewable output from the program
- * being run will be generated.
- *
- * If timeout is specified, the command will be terminated after
- * timeout expires.
- */
- static bool RunCommand(const char* command, std::string& output,
- const char* directory = 0,
- bool verbose = true, int timeout = 0);
- static bool RunCommand(const char* command, std::string& output,
- int &retVal, const char* directory = 0,
- bool verbose = true, int timeout = 0);
- /**
* Run a single executable command
*
* Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no
@@ -312,14 +295,6 @@ public:
*/
static FileFormat GetFileFormat(const char* ext);
- /**
- * On Windows 9x we need a comspec (command.com) substitute to run
- * programs correctly. This string has to be constant available
- * through the running of program. This method does not create a copy.
- */
- static void SetWindows9xComspecSubstitute(const char*);
- static const char* GetWindows9xComspecSubstitute();
-
/** Windows if this is true, the CreateProcess in RunCommand will
* not show new consol windows when running programs.
*/
@@ -488,8 +463,6 @@ private:
static void* s_ErrorCallbackClientData;
static void* s_StdoutCallbackClientData;
static void* s_InterruptCallbackClientData;
-
- static std::string s_Windows9xComspecSubstitute;
};
#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bd37a54..6e5e0ff 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1934,19 +1934,56 @@ static void processIncludeDirectories(cmTarget *tgt,
}
}
std::string usedIncludes;
+ cmListFileBacktrace lfbt;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
- cmTarget *dependentTarget =
- mf->FindTargetToUse((*it)->TargetName.c_str());
+ std::string targetName = (*it)->TargetName;
+ std::string evaluatedTargetName;
+ {
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(targetName);
+ evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0);
+ }
+
+ cmTarget *dependentTarget = mf->FindTargetToUse(targetName.c_str());
const bool fromImported = dependentTarget
&& dependentTarget->IsImported();
- if (fromImported && !cmSystemTools::FileExists(li->c_str()))
+ cmTarget *evaluatedDependentTarget =
+ (targetName != evaluatedTargetName)
+ ? mf->FindTargetToUse(evaluatedTargetName.c_str())
+ : 0;
+
+ targetName = evaluatedTargetName;
+
+ const bool fromEvaluatedImported = evaluatedDependentTarget
+ && evaluatedDependentTarget->IsImported();
+
+ if ((fromImported || fromEvaluatedImported)
+ && !cmSystemTools::FileExists(li->c_str()))
{
cmOStringStream e;
- e << "Imported target \"" << (*it)->TargetName << "\" includes "
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ if (fromEvaluatedImported)
+ {
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0027))
+ {
+ case cmPolicies::WARN:
+ e << (mf->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0027)) << "\n";
+ case cmPolicies::OLD:
+ messageType = cmake::AUTHOR_WARNING;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ e << "Imported target \"" << targetName << "\" includes "
"non-existent path\n \"" << *li << "\"\nin its "
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
"* The path was deleted, renamed, or moved to another "
@@ -1955,7 +1992,7 @@ static void processIncludeDirectories(cmTarget *tgt,
"successfully.\n"
"* The installation package was faulty and references files it "
"does not provide.\n";
- tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ tgt->GetMakefile()->IssueMessage(messageType, e.str().c_str());
return;
}
@@ -1964,9 +2001,9 @@ static void processIncludeDirectories(cmTarget *tgt,
cmOStringStream e;
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
- if (!(*it)->TargetName.empty())
+ if (!targetName.empty())
{
- e << "Target \"" << (*it)->TargetName << "\" contains relative "
+ e << "Target \"" << targetName << "\" contains relative "
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
" \"" << *li << "\"";
}
@@ -1976,7 +2013,6 @@ static void processIncludeDirectories(cmTarget *tgt,
{
case cmPolicies::WARN:
{
- cmOStringStream w;
e << (mf->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0021)) << "\n";
messageType = cmake::AUTHOR_WARNING;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 22f6a03..0707c62 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -151,7 +151,8 @@ bool cmTargetLinkLibrariesCommand
else if(args[i] == "LINK_PUBLIC")
{
if(i != 1
- && this->CurrentProcessingState != ProcessingPlainPrivateInterface)
+ && this->CurrentProcessingState != ProcessingPlainPrivateInterface
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -181,7 +182,8 @@ bool cmTargetLinkLibrariesCommand
else if(args[i] == "LINK_PRIVATE")
{
if(i != 1
- && this->CurrentProcessingState != ProcessingPlainPublicInterface)
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface
+ && this->CurrentProcessingState != ProcessingPlainPrivateInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx
deleted file mode 100644
index 1bdeffb..0000000
--- a/Source/cmWin32ProcessExecution.cxx
+++ /dev/null
@@ -1,884 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmWin32ProcessExecution.h"
-
-#include "cmSystemTools.h"
-
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <windows.h>
-
-#if defined(__BORLANDC__)
-# define STRICMP stricmp
-# define TO_INTPTR(x) ((long)(x))
-#endif // Borland
-#if defined(_MSC_VER) // Visual studio
-# if ( _MSC_VER >= 1300 )
-# include <stddef.h>
-# define TO_INTPTR(x) ((intptr_t)(x))
-# else // Visual Studio 6
-# define TO_INTPTR(x) ((long)(x))
-# endif // Visual studio .NET
-# define STRICMP _stricmp
-#endif // Visual Studio
-#if defined(__MINGW32__)
-# include <stdint.h>
-# define TO_INTPTR(x) ((intptr_t)(x))
-# define STRICMP _stricmp
-#endif // MinGW
-
-#define POPEN_1 1
-#define POPEN_2 2
-#define POPEN_3 3
-#define POPEN_4 4
-
-#define cmMAX(x,y) (((x)<(y))?(y):(x))
-
-void DisplayErrorMessage()
-{
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- // Process any inserts in lpMsgBuf.
- // ...
- // Display the string.
- MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
- // Free the buffer.
- LocalFree( lpMsgBuf );
-}
-
-// Code from a Borland web site with the following explaination :
-/* In this article, I will explain how to spawn a console application
- * and redirect its standard input/output using anonymous pipes. An
- * anonymous pipe is a pipe that goes only in one direction (read
- * pipe, write pipe, etc.). Maybe you are asking, "why would I ever
- * need to do this sort of thing?" One example would be a Windows
- * telnet server, where you spawn a shell and listen on a port and
- * send and receive data between the shell and the socket
- * client. (Windows does not really have a built-in remote
- * shell). First, we should talk about pipes. A pipe in Windows is
- * simply a method of communication, often between process. The SDK
- * defines a pipe as "a communication conduit with two ends;
- a process
- * with a handle to one end can communicate with a process having a
- * handle to the other end." In our case, we are using "anonymous"
- * pipes, one-way pipes that "transfer data between a parent process
- * and a child process or between two child processes of the same
- * parent process." It's easiest to imagine a pipe as its namesake. An
- * actual pipe running between processes that can carry data. We are
- * using anonymous pipes because the console app we are spawning is a
- * child process. We use the CreatePipe function which will create an
- * anonymous pipe and return a read handle and a write handle. We will
- * create two pipes, on for stdin and one for stdout. We will then
- * monitor the read end of the stdout pipe to check for display on our
- * child process. Every time there is something availabe for reading,
- * we will display it in our app. Consequently, we check for input in
- * our app and send it off to the write end of the stdin pipe. */
-
-inline bool IsWinNT()
-//check if we're running NT
-{
- OSVERSIONINFO osv;
- osv.dwOSVersionInfoSize = sizeof(osv);
- GetVersionEx(&osv);
- return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
-}
-
-//---------------------------------------------------------------------------
-bool cmWin32ProcessExecution::BorlandRunCommand(
- const char* command, const char* dir,
- std::string& output, int& retVal, bool verbose, int /* timeout */,
- bool hideWindows)
-{
- //verbose = true;
- //std::cerr << std::endl
- // << "WindowsRunCommand(" << command << ")" << std::endl
- // << std::flush;
- const int BUFFER_SIZE = 4096;
- char buf[BUFFER_SIZE];
-
-//i/o buffer
- STARTUPINFO si;
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
-//security information for pipes
- PROCESS_INFORMATION pi;
- HANDLE newstdin,newstdout,read_stdout,write_stdin;
-
-//pipe handles
- if (IsWinNT())
-//initialize security descriptor (Windows NT)
- {
- InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&sd, true, NULL, false);
- sa.lpSecurityDescriptor = &sd;
-
- }
- else sa.lpSecurityDescriptor = NULL;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = true;
-
-//allow inheritable handles
- if (!CreatePipe(&newstdin,&write_stdin,&sa,0))
-//create stdin pipe
- {
- return false;
- }
- if (!CreatePipe(&read_stdout,&newstdout,&sa,0))
-//create stdout pipe
- {
- CloseHandle(newstdin);
- CloseHandle(write_stdin);
- return false;
-
- }
- GetStartupInfo(&si);
-
-//set startupinfo for the spawned process
- /* The dwFlags member tells CreateProcess how to make the
- * process. STARTF_USESTDHANDLES validates the hStd*
- * members. STARTF_USESHOWWINDOW validates the wShowWindow
- * member. */
-
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- si.hStdOutput = newstdout;
- si.hStdError = newstdout;
- si.wShowWindow = SW_SHOWDEFAULT;
- if(hideWindows)
- {
- si.wShowWindow = SW_HIDE;
- }
-
-//set the new handles for the child process si.hStdInput = newstdin;
- char* commandAndArgs = strcpy(new char[strlen(command)+1], command);
- if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE,
- 0, // CREATE_NEW_CONSOLE,
- NULL,dir,&si,&pi))
- {
- std::cerr << "CreateProcess failed " << commandAndArgs << std::endl;
- CloseHandle(newstdin);
- CloseHandle(newstdout);
- CloseHandle(read_stdout);
- CloseHandle(write_stdin);
- delete [] commandAndArgs;
- return false;
-
- }
- delete [] commandAndArgs;
- unsigned long exit=0;
-
-//process exit code unsigned
- unsigned long bread;
-
-//bytes read unsigned
- unsigned long avail;
-
-//bytes available
- memset(buf, 0, sizeof(buf));
- for(;;)
-//main program loop
- {
- Sleep(10);
-//check to see if there is any data to read from stdout
- //std::cout << "Peek for data..." << std::endl;
- PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
- if (bread != 0)
- {
- memset(buf, 0, sizeof(buf));
- if (avail > 1023)
- {
- while (bread >= 1023)
- {
- //std::cout << "Read data..." << std::endl;
- ReadFile(read_stdout,buf,1023,&bread,NULL);
-
- //read the stdout pipe
- memset(buf, 0, sizeof(buf));
- output += buf;
- if (verbose)
- {
- cmSystemTools::Stdout(buf);
- }
- }
- }
- else
- {
- ReadFile(read_stdout,buf,1023,&bread,NULL);
- output += buf;
- if(verbose)
- {
- cmSystemTools::Stdout(buf);
- }
-
- }
-
- }
-
- //std::cout << "Check for process..." << std::endl;
- GetExitCodeProcess(pi.hProcess,&exit);
-
-//while the process is running
- if (exit != STILL_ACTIVE) break;
-
- }
- WaitForSingleObject(pi.hProcess, INFINITE);
- GetExitCodeProcess(pi.hProcess,&exit);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- CloseHandle(newstdin);
-
-//clean stuff up
- CloseHandle(newstdout);
- CloseHandle(read_stdout);
- CloseHandle(write_stdin);
- retVal = exit;
- return true;
-
-}
-
-bool cmWin32ProcessExecution::StartProcess(
- const char* cmd, const char* path, bool verbose)
-{
- this->Initialize();
- this->Verbose = verbose;
- return this->PrivateOpen(cmd, path, _O_RDONLY | _O_TEXT, POPEN_3);
-}
-
-bool cmWin32ProcessExecution::Wait(int timeout)
-{
- return this->PrivateClose(timeout);
-}
-
-static BOOL RealPopenCreateProcess(const char *cmdstring,
- const char *path,
- const char *szConsoleSpawn,
- HANDLE hStdin,
- HANDLE hStdout,
- HANDLE hStderr,
- HANDLE *hProcess,
- bool hideWindows,
- std::string& output)
-{
- PROCESS_INFORMATION piProcInfo;
- STARTUPINFO siStartInfo;
- char *s1=0,*s2=0;
- const char *s3 = " /c ";
- int i = GetEnvironmentVariable("COMSPEC",NULL,0);
- if (i)
- {
- char *comshell;
-
- s1 = (char *)malloc(i);
- int x = GetEnvironmentVariable("COMSPEC", s1, i);
- if (!x)
- {
- free(s1);
- return x;
- }
-
- /* Explicitly check if we are using COMMAND.COM. If we are
- * then use the w9xpopen hack.
- */
- comshell = s1 + x;
- while (comshell >= s1 && *comshell != '\\')
- --comshell;
- ++comshell;
-
- if (GetVersion() < 0x80000000 &&
- STRICMP(comshell, "command.com") != 0)
- {
- /* NT/2000 and not using command.com. */
- x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1;
- s2 = (char *)malloc(x);
- ZeroMemory(s2, x);
- //sprintf(s2, "%s%s%s", s1, s3, cmdstring);
- sprintf(s2, "%s", cmdstring);
- }
- else
- {
- /*
- * Oh gag, we're on Win9x or using COMMAND.COM. Use
- * the workaround listed in KB: Q150956
- */
- char modulepath[_MAX_PATH];
- struct stat statinfo;
- GetModuleFileName(NULL, modulepath, sizeof(modulepath));
- for (i = x = 0; modulepath[i]; i++)
- if (modulepath[i] == '\\')
- x = i+1;
- modulepath[x] = '\0';
- /* Create the full-name to w9xpopen, so we can test it exists */
- strncat(modulepath,
- szConsoleSpawn,
- (sizeof(modulepath)/sizeof(modulepath[0]))
- -strlen(modulepath));
- if (stat(modulepath, &statinfo) != 0)
- {
- /* Eeek - file-not-found - possibly an embedding
- situation - see if we can locate it in sys.prefix
- */
- strncpy(modulepath,
- ".",
- sizeof(modulepath)/sizeof(modulepath[0]));
- if (modulepath[strlen(modulepath)-1] != '\\')
- strcat(modulepath, "\\");
- strncat(modulepath,
- szConsoleSpawn,
- (sizeof(modulepath)/sizeof(modulepath[0]))
- -strlen(modulepath));
- /* No where else to look - raise an easily identifiable
- error, rather than leaving Windows to report
- "file not found" - as the user is probably blissfully
- unaware this shim EXE is used, and it will confuse them.
- (well, it confused me for a while ;-)
- */
- if (stat(modulepath, &statinfo) != 0)
- {
- std::cout
- << "Can not locate '" << modulepath
- << "' which is needed "
- "for popen to work with your shell "
- "or platform." << std::endl;
- free(s1);
- free(s2);
- return FALSE;
- }
- }
- x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 +
- (int)strlen(modulepath) +
- (int)strlen(szConsoleSpawn) + 1;
- if(s2)
- {
- free(s2);
- }
- s2 = (char *)malloc(x);
- ZeroMemory(s2, x);
- sprintf(
- s2,
- "%s %s%s%s",
- modulepath,
- s1,
- s3,
- cmdstring);
- sprintf(
- s2,
- "%s %s",
- modulepath,
- cmdstring);
- }
- }
-
- /* Could be an else here to try cmd.exe / command.com in the path
- Now we'll just error out.. */
- else
- {
- std::cout << "Cannot locate a COMSPEC environment variable to "
- << "use as the shell" << std::endl;
- free(s2);
- free(s1);
- return FALSE;
- }
-
- ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
- siStartInfo.cb = sizeof(STARTUPINFO);
- siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- siStartInfo.hStdInput = hStdin;
- siStartInfo.hStdOutput = hStdout;
- siStartInfo.hStdError = hStderr;
- siStartInfo.wShowWindow = SW_SHOWDEFAULT;
- if(hideWindows)
- {
- siStartInfo.wShowWindow = SW_HIDE;
- }
-
- //std::cout << "Create process: " << s2 << std::endl;
- if (CreateProcess(NULL,
- s2,
- NULL,
- NULL,
- TRUE,
- 0, //CREATE_NEW_CONSOLE,
- NULL,
- path,
- &siStartInfo,
- &piProcInfo) )
- {
- /* Close the handles now so anyone waiting is woken. */
- CloseHandle(piProcInfo.hThread);
- /* Return process handle */
- *hProcess = piProcInfo.hProcess;
- //std::cout << "Process created..." << std::endl;
- free(s2);
- free(s1);
- return TRUE;
- }
-
- output += "CreateProcessError: ";
- {
- /* Format the error message. */
- char message[1024];
- DWORD original = GetLastError();
- DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- message, 1023, 0);
- if(length < 1)
- {
- /* FormatMessage failed. Use a default message. */
- _snprintf(message, 1023,
- "Process execution failed with error 0x%X. "
- "FormatMessage failed with error 0x%X",
- original, GetLastError());
- }
- output += message;
- }
- output += "\n";
- output += "for command: ";
- output += s2;
- if(path)
- {
- output += "\nin dir: ";
- output += path;
- }
- output += "\n";
- free(s2);
- free(s1);
- return FALSE;
-}
-
-/* The following code is based off of KB: Q190351 */
-
-bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
- const char* path,
- int mode,
- int n)
-{
- HANDLE hProcess;
-
- SECURITY_ATTRIBUTES saAttr;
- BOOL fSuccess;
- int fd1, fd2, fd3;
- this->hChildStdinRd = 0;
- this->hChildStdinWr = 0;
- this->hChildStdoutRd = 0;
- this->hChildStdoutWr = 0;
- this->hChildStderrRd = 0;
- this->hChildStderrWr = 0;
- this->hChildStdinWrDup = 0;
- this->hChildStdoutRdDup = 0;
- this->hChildStderrRdDup = 0;
-
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- fd1 = 0;
- fd2 = 0;
- fd3 = 0;
-
- if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
-
- /* Create new output read handle and the input write handle. Set
- * the inheritance properties to FALSE. Otherwise, the child inherits
- * these handles; resulting in non-closeable handles to the pipes
- * being created. */
- fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr,
- GetCurrentProcess(), &this->hChildStdinWrDup, 0,
- FALSE,
- DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
-
-
- /* Close the inheritable version of ChildStdin
- that we're using. */
- CloseHandle(hChildStdinWr);
-
- if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
-
- fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd,
- GetCurrentProcess(), &this->hChildStdoutRdDup, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
-
- /* Close the inheritable version of ChildStdout
- that we're using. */
- CloseHandle(hChildStdoutRd);
-
- if (n != POPEN_4)
- {
- if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
- fSuccess = DuplicateHandle(GetCurrentProcess(),
- this->hChildStderrRd,
- GetCurrentProcess(),
- &this->hChildStderrRdDup, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
- /* Close the inheritable version of ChildStdErr that we're using. */
- CloseHandle(hChildStderrRd);
-
- }
-
- switch (n)
- {
- case POPEN_1:
- switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY))
- {
- case _O_WRONLY | _O_TEXT:
- /* Case for writing to child Stdin in text mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_RDONLY | _O_TEXT:
- /* Case for reading from child Stdout in text mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_RDONLY | _O_BINARY:
- /* Case for readinig from child Stdout in
- binary mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_WRONLY | _O_BINARY:
- /* Case for writing to child Stdin in binary mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
- }
- break;
-
- case POPEN_2:
- case POPEN_4:
- //if ( 1 )
- {
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- break;
- }
-
- case POPEN_3:
- //if ( 1)
- {
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode);
- break;
- }
- }
-
- if (n == POPEN_4)
- {
- if (!RealPopenCreateProcess(cmdstring,
- path,
- this->ConsoleSpawn.c_str(),
- this->hChildStdinRd,
- this->hChildStdoutWr,
- this->hChildStdoutWr,
- &hProcess, this->HideWindows,
- this->Output))
- {
- if(fd1 >= 0)
- {
- close(fd1);
- }
- if(fd2 >= 0)
- {
- close(fd2);
- }
- if(fd3 >= 0)
- {
- close(fd3);
- }
- return 0;
- }
- }
- else
- {
- if (!RealPopenCreateProcess(cmdstring,
- path,
- this->ConsoleSpawn.c_str(),
- this->hChildStdinRd,
- this->hChildStdoutWr,
- this->hChildStderrWr,
- &hProcess, this->HideWindows,
- this->Output))
- {
- if(fd1 >= 0)
- {
- close(fd1);
- }
- if(fd2 >= 0)
- {
- close(fd2);
- }
- if(fd3 >= 0)
- {
- close(fd3);
- }
- return 0;
- }
- }
-
- /* Child is launched. Close the parents copy of those pipe
- * handles that only the child should have open. You need to
- * make sure that no handles to the write end of the output pipe
- * are maintained in this process or else the pipe will not close
- * when the child process exits and the ReadFile will hang. */
- this->ProcessHandle = hProcess;
- if ( fd1 >= 0 )
- {
- this->pStdIn = fd1;
- }
- if ( fd2 >= 0 )
- {
- this->pStdOut = fd2;
- }
- if ( fd3 >= 0 )
- {
- this->pStdErr = fd3;
- }
-
- return true;
-}
-
-bool cmWin32ProcessExecution::CloseHandles()
-{
- if(this->pStdErr != -1 )
- {
- // this will close this as well: this->hChildStderrRdDup
- _close(this->pStdErr);
- this->pStdErr = -1;
- this->hChildStderrRdDup = 0;
- }
- if(this->pStdIn != -1 )
- {
- // this will close this as well: this->hChildStdinWrDup
- _close(this->pStdIn);
- this->pStdIn = -1;
- this->hChildStdinWrDup = 0;
- }
- if(this->pStdOut != -1 )
- {
- // this will close this as well: this->hChildStdoutRdDup
- _close(this->pStdOut);
- this->pStdOut = -1;
- this->hChildStdoutRdDup = 0;
- }
-
- bool ret = true;
- if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
- {
- ret = false;
- }
- this->hChildStdinRd = 0;
- // now close these two
- if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
- {
- ret = false;
- }
- this->hChildStdoutWr = 0;
- if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
- {
- ret = false;
- }
- this->hChildStderrWr = 0;
- return ret;
-}
-cmWin32ProcessExecution::~cmWin32ProcessExecution()
-{
- this->CloseHandles();
-}
-
-bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
-{
- HANDLE hProcess = this->ProcessHandle;
-
- int result = -1;
- DWORD exit_code;
-
- std::string output = "";
- bool done = false;
- while(!done)
- {
- Sleep(10);
- bool have_some = false;
- struct _stat fsout;
- struct _stat fserr;
- int rout = _fstat(this->pStdOut, &fsout);
- int rerr = _fstat(this->pStdErr, &fserr);
- if ( rout && rerr )
- {
- break;
- }
- if (fserr.st_size > 0)
- {
- char buffer[1024];
- int len = read(this->pStdErr, buffer, 1023);
- buffer[len] = 0;
- if ( this->Verbose )
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- have_some = true;
- }
- if (fsout.st_size > 0)
- {
- char buffer[1024];
- int len = read(this->pStdOut, buffer, 1023);
- buffer[len] = 0;
- if ( this->Verbose )
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- have_some = true;
- }
- unsigned long exitCode;
- if ( ! have_some )
- {
- GetExitCodeProcess(hProcess,&exitCode);
- if (exitCode != STILL_ACTIVE)
- {
- break;
- }
- }
- }
-
-
- if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
- GetExitCodeProcess(hProcess, &exit_code))
- {
- result = exit_code;
- }
- else
- {
- /* Indicate failure - this will cause the file object
- * to raise an I/O error and translate the last Win32
- * error code from errno. We do have a problem with
- * last errors that overlap the normal errno table,
- * but that's a consistent problem with the file object.
- */
- if (result != EOF)
- {
- /* If the error wasn't from the fclose(), then
- * set errno for the file object error handling.
- */
- errno = GetLastError();
- }
- result = -1;
- }
-
- /* Free up the native handle at this point */
- CloseHandle(hProcess);
- this->ExitValue = result;
- this->Output += output;
- bool ret = this->CloseHandles();
- if ( result < 0 || !ret)
- {
- return false;
- }
- return true;
-}
-
-int cmWin32ProcessExecution::Windows9xHack(const char* command)
-{
- BOOL bRet;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- DWORD exit_code=0;
-
- if (!command)
- {
- cmSystemTools::Error("Windows9xHack: Command not specified");
- return 1;
- }
-
- /* Make child process use this app's standard files. */
- ZeroMemory(&si, sizeof si);
- si.cb = sizeof si;
- si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
-
- char * app = 0;
- char* cmd = new char[ strlen(command) + 1 ];
- strcpy(cmd, command);
-
- bRet = CreateProcess(
- app, cmd,
- 0, 0,
- TRUE, 0,
- 0, 0,
- &si, &pi
- );
- delete [] cmd;
-
- if (bRet)
- {
- if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED)
- {
- GetExitCodeProcess(pi.hProcess, &exit_code);
- }
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- return exit_code;
- }
-
- return 1;
-}
diff --git a/Source/cmWin32ProcessExecution.h b/Source/cmWin32ProcessExecution.h
deleted file mode 100644
index 2127ebd2..0000000
--- a/Source/cmWin32ProcessExecution.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmWin32ProcessExecution_h
-#define cmWin32ProcessExecution_h
-
-#include "cmStandardIncludes.h"
-#include "windows.h"
-
-class cmMakefile;
-
-/** \class cmWin32ProcessExecution
- * \brief A process executor for windows
- *
- * cmWin32ProcessExecution is a class that provides a "clean" way of
- * executing processes on Windows. It is modified code from Python 2.1
- * distribution.
- *
- * Portable 'popen' replacement for Win32.
- *
- * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks and 2.0
- * integration by Fredrik Lundh <fredrik@pythonware.com> Return code
- * handling by David Bolen <db3l@fitlinxx.com>.
- *
- * Modified for CMake.
- *
- * For more information, please check Microsoft Knowledge Base
- * Articles Q190351 and Q150956.
- */
-class cmWin32ProcessExecution
-{
-public:
- cmWin32ProcessExecution()
- {
- this->HideWindows = false;
- this->SetConsoleSpawn("w9xpopen.exe");
- this->Initialize();
- }
- ~cmWin32ProcessExecution();
- ///! If true windows will be created hidden.
- void SetHideWindows(bool v) { this->HideWindows = v; }
-
- /**
- * Initialize the process execution datastructure. Do not call while
- * running the process.
- */
- void Initialize()
- {
- this->ProcessHandle = 0;
- this->ExitValue = -1;
- // Comment this out. Maybe we will need it in the future.
- // file IO access to the process might be cool.
- //this->StdIn = 0;
- //this->StdOut = 0;
- //this->StdErr = 0;
- this->pStdIn = -1;
- this->pStdOut = -1;
- this->pStdErr = -1;
- }
-
- /**
- * Start the process in the directory path. Make sure that the
- * executable is either in the path or specify the full path. The
- * argument verbose specifies whether or not to display output while
- * it is being generated.
- */
- bool StartProcess(const char*, const char* path, bool verbose);
-
- /**
- * Wait for the process to finish. If timeout is specified, it will
- * break the process after timeout expires. (Timeout code is not yet
- * implemented.
- */
- bool Wait(int timeout);
-
- /**
- * Get the output of the process (mixed stdout and stderr) as
- * std::string.
- */
- const std::string GetOutput() const { return this->Output; }
-
- /**
- * Get the return value of the process. If the process is still
- * running, the return value is -1.
- */
- int GetExitValue() const { return this->ExitValue; }
-
- /**
- * On Windows 9x there is a bug in the process execution code which
- * may result in blocking. That is why this workaround is
- * used. Specify the console spawn, which should run the
- * Windows9xHack code.
- */
- void SetConsoleSpawn(const char* prog) { this->ConsoleSpawn = prog; }
- static int Windows9xHack(const char* command);
-
- /** Code from a Borland web site with the following explaination :
- * In this article, I will explain how to spawn a console
- * application and redirect its standard input/output using
- * anonymous pipes. An anonymous pipe is a pipe that goes only in
- * one direction (read pipe, write pipe, etc.). Maybe you are
- * asking, "why would I ever need to do this sort of thing?" One
- * example would be a Windows telnet server, where you spawn a shell
- * and listen on a port and send and receive data between the shell
- * and the socket client. (Windows does not really have a built-in
- * remote shell). First, we should talk about pipes. A pipe in
- * Windows is simply a method of communication, often between
- * process. The SDK defines a pipe as "a communication conduit with
- * two ends; a process with a handle to one end can communicate with
- * a process having a handle to the other end." In our case, we are
- * using "anonymous" pipes, one-way pipes that "transfer data
- * between a parent process and a child process or between two child
- * processes of the same parent process." It's easiest to imagine a
- * pipe as its namesake. An actual pipe running between processes
- * that can carry data. We are using anonymous pipes because the
- * console app we are spawning is a child process. We use the
- * CreatePipe function which will create an anonymous pipe and
- * return a read handle and a write handle. We will create two
- * pipes, on for stdin and one for stdout. We will then monitor the
- * read end of the stdout pipe to check for display on our child
- * process. Every time there is something availabe for reading, we
- * will display it in our app. Consequently, we check for input in
- * our app and send it off to the write end of the stdin pipe.
- */
- static bool BorlandRunCommand(const char* command,
- const char* dir,
- std::string& output, int& retVal,
- bool verbose,
- int timeout, bool hideWindows);
-
-private:
- bool CloseHandles();
- bool PrivateOpen(const char*, const char*, int, int);
- bool PrivateClose(int timeout);
-
- HANDLE ProcessHandle;
- HANDLE hChildStdinRd;
- HANDLE hChildStdinWr;
- HANDLE hChildStdoutRd;
- HANDLE hChildStdoutWr;
- HANDLE hChildStderrRd;
- HANDLE hChildStderrWr;
- HANDLE hChildStdinWrDup;
- HANDLE hChildStdoutRdDup;
- HANDLE hChildStderrRdDup;
-
-
- int pStdIn;
- int pStdOut;
- int pStdErr;
-
- int ExitValue;
-
- std::string Output;
- std::string ConsoleSpawn;
- bool Verbose;
- bool HideWindows;
-};
-
-
-#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index d11a40b..9c79516 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1104,10 +1104,6 @@ int cmake::AddCMakePaths()
("CMAKE_ROOT", cMakeRoot.c_str(),
"Path to CMake installation.", cmCacheManager::INTERNAL);
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
return 1;
}
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 6e2125f..5113a75 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -79,32 +79,22 @@ static const char * cmDocumentationOptions[][2] =
{"--no-warn-unused-cli", "Don't warn about command line options."},
{"--check-system-vars", "Find problems with variable usage in system "
"files."},
- {"--help-command cmd [file]", "Print help for a single command and exit."},
- {"--help-command-list [file]", "List available listfile commands and exit."},
- {"--help-commands [file]", "Print help for all commands and exit."},
- {"--help-compatcommands [file]", "Print help for compatibility commands. "},
- {"--help-module module [file]", "Print help for a single module and exit."},
- {"--help-module-list [file]", "List available modules and exit."},
- {"--help-modules [file]", "Print help for all modules and exit."},
- {"--help-custom-modules [file]" , "Print help for all custom modules and "
- "exit."},
- {"--help-policy cmp [file]",
- "Print help for a single policy and exit."},
- {"--help-policy-list [file]", "List available policies and exit."},
- {"--help-policies [file]", "Print help for all policies and exit."},
- {"--help-property prop [file]",
- "Print help for a single property and exit."},
- {"--help-property-list [file]", "List available properties and exit."},
- {"--help-properties [file]", "Print help for all properties and exit."},
- {"--help-variable var [file]",
- "Print help for a single variable and exit."},
- {"--help-variable-list [file]", "List documented variables and exit."},
- {"--help-variables [file]", "Print help for all variables and exit."},
{0,0}
};
#endif
+static int do_command(int ac, char** av)
+{
+ std::vector<std::string> args;
+ args.push_back(av[0]);
+ for(int i = 2; i < ac; ++i)
+ {
+ args.push_back(av[i]);
+ }
+ return cmcmd::ExecuteCMakeCommand(args);
+}
+
int do_cmake(int ac, char** av);
static int do_build(int ac, char** av);
@@ -178,9 +168,16 @@ int main(int ac, char** av)
{
cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::FindExecutableDirectory(av[0]);
- if(ac > 1 && strcmp(av[1], "--build") == 0)
+ if(ac > 1)
{
- return do_build(ac, av);
+ if(strcmp(av[1], "--build") == 0)
+ {
+ return do_build(ac, av);
+ }
+ else if(strcmp(av[1], "-E") == 0)
+ {
+ return do_command(ac, av);
+ }
}
int ret = do_cmake(ac, av);
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -201,7 +198,7 @@ int do_cmake(int ac, char** av)
#ifdef CMAKE_BUILD_WITH_CMAKE
cmDocumentation doc;
doc.addCMakeStandardDocSections();
- if(doc.CheckOptions(ac, av, "-E"))
+ if(doc.CheckOptions(ac, av))
{
// Construct and print requested documentation.
cmake hcm;
@@ -241,7 +238,6 @@ int do_cmake(int ac, char** av)
bool wiz = false;
bool sysinfo = false;
- bool command = false;
bool list_cached = false;
bool list_all_cached = false;
bool list_help = false;
@@ -250,43 +246,37 @@ int do_cmake(int ac, char** av)
std::vector<std::string> args;
for(int i =0; i < ac; ++i)
{
- if(!command && strcmp(av[i], "-i") == 0)
+ if(strcmp(av[i], "-i") == 0)
{
wiz = true;
}
- else if(!command && strcmp(av[i], "--system-information") == 0)
+ else if(strcmp(av[i], "--system-information") == 0)
{
sysinfo = true;
}
- // if command has already been set, then
- // do not eat the -E
- else if (!command && strcmp(av[i], "-E") == 0)
- {
- command = true;
- }
- else if (!command && strcmp(av[i], "-N") == 0)
+ else if (strcmp(av[i], "-N") == 0)
{
view_only = true;
}
- else if (!command && strcmp(av[i], "-L") == 0)
+ else if (strcmp(av[i], "-L") == 0)
{
list_cached = true;
}
- else if (!command && strcmp(av[i], "-LA") == 0)
+ else if (strcmp(av[i], "-LA") == 0)
{
list_all_cached = true;
}
- else if (!command && strcmp(av[i], "-LH") == 0)
+ else if (strcmp(av[i], "-LH") == 0)
{
list_cached = true;
list_help = true;
}
- else if (!command && strcmp(av[i], "-LAH") == 0)
+ else if (strcmp(av[i], "-LAH") == 0)
{
list_all_cached = true;
list_help = true;
}
- else if (!command && strncmp(av[i], "-P", strlen("-P")) == 0)
+ else if (strncmp(av[i], "-P", strlen("-P")) == 0)
{
if ( i == ac -1 )
{
@@ -300,8 +290,8 @@ int do_cmake(int ac, char** av)
args.push_back(av[i]);
}
}
- else if (!command && strncmp(av[i], "--find-package",
- strlen("--find-package")) == 0)
+ else if (strncmp(av[i], "--find-package",
+ strlen("--find-package")) == 0)
{
workingMode = cmake::FIND_PACKAGE_MODE;
args.push_back(av[i]);
@@ -311,11 +301,6 @@ int do_cmake(int ac, char** av)
args.push_back(av[i]);
}
}
- if(command)
- {
- int ret = cmcmd::ExecuteCMakeCommand(args);
- return ret;
- }
if (wiz)
{
cmakewizard wizard;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 48d7d7b..9814aea 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -29,10 +29,6 @@
#include "cmVisualStudioWCEPlatformParser.h"
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# include "cmWin32ProcessExecution.h"
-#endif
-
#include <time.h>
#include <stdlib.h> // required for atoi
@@ -79,7 +75,6 @@ void CMakeCommandUsage(const char* program)
<< " touch_nocreate file - touch a file but do not create it.\n"
#if defined(_WIN32) && !defined(__CYGWIN__)
<< "Available on Windows only:\n"
- << " comspec - on windows 9x use this for RunCommand\n"
<< " delete_regv key - delete registry value\n"
<< " env_vs8_wince sdkname - displays a batch file which sets the "
"environment for the provided Windows CE SDK installed in VS2005\n"
@@ -743,13 +738,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
// Remove file
else if (args[1] == "comspec" && args.size() > 2)
{
- unsigned int cc;
- std::string command = args[2];
- for ( cc = 3; cc < args.size(); cc ++ )
- {
- command += " " + args[cc];
- }
- return cmWin32ProcessExecution::Windows9xHack(command.c_str());
+ std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n";
+ return 1;
}
else if (args[1] == "env_vs8_wince" && args.size() == 3)
{
diff --git a/Source/cmw9xcom.cxx b/Source/cmw9xcom.cxx
deleted file mode 100644
index ab238d5..0000000
--- a/Source/cmw9xcom.cxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmSystemTools.h"
-#include "cmWin32ProcessExecution.h"
-
-// this is a test driver program for cmake.
-int main (int argc, char *argv[])
-{
- cmSystemTools::EnableMSVCDebugHook();
- if ( argc <= 1 )
- {
- std::cerr << "Usage: " << argv[0] << " executable" << std::endl;
- return 1;
- }
- std::string arg = argv[1];
- if ( (arg.find_first_of(" ") != arg.npos) &&
- (arg.find_first_of("\"") == arg.npos) )
- {
- arg = "\"" + arg + "\"";
- }
- std::string command = arg;
- int cc;
- for ( cc = 2; cc < argc; cc ++ )
- {
- std::string nextArg = argv[cc];
- if ( (nextArg.find_first_of(" ") != nextArg.npos) &&
- (nextArg.find_first_of("\"") == nextArg.npos) )
- {
- nextArg = "\"" + nextArg + "\"";
- }
- command += " ";
- command += nextArg;
- }
-
- return cmWin32ProcessExecution::Windows9xHack(command.c_str());
-}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 6e3a86b..12e71b6 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -107,10 +107,6 @@ static const char * cmDocumentationOptions[][2] =
{"--http1.0", "Submit using HTTP 1.0."},
{"--no-compress-output", "Do not compress test output when submitting."},
{"--print-labels", "Print all available test labels."},
- {"--help-command <cmd> [<file>]",
- "Show help for a single command and exit."},
- {"--help-command-list [<file>]", "List available commands and exit."},
- {"--help-commands [<file>]", "Print help for all commands and exit."},
{0,0}
};
@@ -153,6 +149,10 @@ int main (int argc, char *argv[])
doc.addCTestStandardDocSections();
if(doc.CheckOptions(argc, argv))
{
+ cmake hcm;
+ hcm.AddCMakePaths();
+ doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
+
// Construct and print requested documentation.
cmCTestScriptHandler* ch =
static_cast<cmCTestScriptHandler*>(inst.GetHandler("script"));
@@ -171,10 +171,6 @@ int main (int argc, char *argv[])
}
}
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
// copy the args to a vector
std::vector<std::string> args;
for(int i =0; i < argc; ++i)