diff options
Diffstat (limited to 'Source')
53 files changed, 3448 insertions, 460 deletions
diff --git a/Source/.gitattributes b/Source/.gitattributes new file mode 100644 index 0000000..cf4dabd --- /dev/null +++ b/Source/.gitattributes @@ -0,0 +1,2 @@ +# Preserve upstream indentation style. +cm_sha2.* whitespace=indent-with-non-tab diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ba41d98..b5115b7 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -129,6 +129,8 @@ SET(SRCS cmComputeLinkInformation.h cmComputeTargetDepends.h cmComputeTargetDepends.cxx + cmCryptoHash.cxx + cmCryptoHash.h cmCustomCommand.cxx cmCustomCommand.h cmCustomCommandGenerator.cxx @@ -160,6 +162,7 @@ SET(SRCS cmDocumentationSection.cxx cmDocumentCompileDefinitions.h cmDocumentGeneratorExpressions.h + cmDocumentLocationUndefined.h cmDocumentVariables.cxx cmDynamicLoader.cxx cmDynamicLoader.h @@ -214,6 +217,8 @@ SET(SRCS cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx + cmNewLineStyle.h + cmNewLineStyle.cxx cmOrderDirectories.cxx cmOrderDirectories.h cmPolicies.h @@ -259,6 +264,8 @@ SET(SRCS cmakewizard.cxx cmakewizard.h + cm_sha2.h + cm_sha2.c cm_utf8.h cm_utf8.c ) diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index b4d9191..00aaf69 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -12,15 +12,16 @@ #include "AddCacheEntry.h" #include <QMetaProperty> +#include <QCompleter> static const int NumTypes = 4; -static const QString TypeStrings[NumTypes] = +static const QString TypeStrings[NumTypes] = { "BOOL", "PATH", "FILEPATH", "STRING" }; -static const QCMakeProperty::PropertyType Types[NumTypes] = - { QCMakeProperty::BOOL, QCMakeProperty::PATH, - QCMakeProperty::FILEPATH, QCMakeProperty::STRING}; +static const QCMakeProperty::PropertyType Types[NumTypes] = + { QCMakeProperty::BOOL, QCMakeProperty::PATH, + QCMakeProperty::FILEPATH, QCMakeProperty::STRING}; -AddCacheEntry::AddCacheEntry(QWidget* p) +AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& completions) : QWidget(p) { this->setupUi(this); @@ -42,6 +43,7 @@ AddCacheEntry::AddCacheEntry(QWidget* p) this->setTabOrder(path, filepath); this->setTabOrder(filepath, string); this->setTabOrder(string, this->Description); + this->Name->setCompleter(new QCompleter(completions, this)); } QString AddCacheEntry::name() const diff --git a/Source/QtDialog/AddCacheEntry.h b/Source/QtDialog/AddCacheEntry.h index db6baf9..e219d4e 100644 --- a/Source/QtDialog/AddCacheEntry.h +++ b/Source/QtDialog/AddCacheEntry.h @@ -15,6 +15,7 @@ #include <QWidget> #include <QCheckBox> +#include <QStringList> #include "QCMake.h" #include "ui_AddCacheEntry.h" @@ -23,7 +24,7 @@ class AddCacheEntry : public QWidget, public Ui::AddCacheEntry { Q_OBJECT public: - AddCacheEntry(QWidget* p); + AddCacheEntry(QWidget* p, const QStringList& completions); QString name() const; QVariant value() const; diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index c8c4bfa..1c058d3 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -68,6 +68,9 @@ CMakeSetupDialog::CMakeSetupDialog() int w = settings.value("Width", 700).toInt(); this->resize(w, h); + this->AddVariableCompletions = settings.value("AddVariableCompletionEntries", + QStringList("CMAKE_INSTALL_PREFIX")).toStringList(); + QWidget* cont = new QWidget(this); this->setupUi(cont); this->Splitter->setStretchFactor(0, 3); @@ -1008,7 +1011,7 @@ void CMakeSetupDialog::addCacheEntry() dialog.resize(400, 200); dialog.setWindowTitle(tr("Add Cache Entry")); QVBoxLayout* l = new QVBoxLayout(&dialog); - AddCacheEntry* w = new AddCacheEntry(&dialog); + AddCacheEntry* w = new AddCacheEntry(&dialog, this->AddVariableCompletions); QDialogButtonBox* btns = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); @@ -1021,6 +1024,26 @@ void CMakeSetupDialog::addCacheEntry() { QCMakeCacheModel* m = this->CacheValues->cacheModel(); m->insertProperty(w->type(), w->name(), w->description(), w->value(), false); + + // only add variable names to the completion which are new + if (!this->AddVariableCompletions.contains(w->name())) + { + this->AddVariableCompletions << w->name(); + // limit to at most 100 completion items + if (this->AddVariableCompletions.size() > 100) + { + this->AddVariableCompletions.removeFirst(); + } + // make sure CMAKE_INSTALL_PREFIX is always there + if (!this->AddVariableCompletions.contains("CMAKE_INSTALL_PREFIX")) + { + this->AddVariableCompletions << QString("CMAKE_INSTALL_PREFIX"); + } + QSettings settings; + settings.beginGroup("Settings/StartPath"); + settings.setValue("AddVariableCompletionEntries", + this->AddVariableCompletions); + } } } diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index 5121759..2599675 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -36,7 +36,7 @@ public slots: void setBinaryDirectory(const QString& dir); void setSourceDirectory(const QString& dir); -protected slots: +protected slots: void initialize(); void doConfigure(); void doGenerate(); @@ -46,7 +46,7 @@ protected slots: void doInterrupt(); void error(const QString& message); void message(const QString& message); - + void doSourceBrowse(); void doBinaryBrowse(); void doReloadCache(); @@ -105,6 +105,8 @@ protected: QTextCharFormat ErrorFormat; QTextCharFormat MessageFormat; + QStringList AddVariableCompletions; + QEventLoop LocalLoop; float ProgressOffset; @@ -118,8 +120,8 @@ class QCMakeThread : public QThread public: QCMakeThread(QObject* p); QCMake* cmakeInstance() const; - -signals: + +signals: void cmakeInitialized(); protected: diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 7bb8b27..3f7fdc7 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -440,8 +440,12 @@ std::string cmCTest::GetCDashVersion() std::string cdashUri = this->GetCTestConfiguration("DropLocation"); cdashUri = cdashUri.substr(0, cdashUri.find("/submit.php")); - url += cdashUri + "/api/getversion.php"; - int res = cmCTest::HTTPRequest(url, cmCTest::HTTP_GET, response, "", "", 3); + int res = 1; + if ( ! cdashUri.empty() ) + { + url += cdashUri + "/api/getversion.php"; + res = cmCTest::HTTPRequest(url, cmCTest::HTTP_GET, response, "", "", 3); + } return res ? this->GetCTestConfiguration("CDashVersion") : response; #else @@ -1441,6 +1445,43 @@ int cmCTest::RunTest(std::vector<const char*> argv, } //---------------------------------------------------------------------- +std::string cmCTest::SafeBuildIdField(const std::string& value) +{ + std::string safevalue(value); + + if (safevalue != "") + { + // Disallow non-filename and non-space whitespace characters. + // If they occur, replace them with "" + // + const char *disallowed = "\\/:*?\"<>|\n\r\t\f\v"; + + if (safevalue.find_first_of(disallowed) != value.npos) + { + std::string::size_type i = 0; + std::string::size_type n = strlen(disallowed); + char replace[2]; + replace[1] = 0; + + for (i= 0; i<n; ++i) + { + replace[0] = disallowed[i]; + cmSystemTools::ReplaceString(safevalue, replace, ""); + } + } + + safevalue = cmXMLSafe(safevalue).str(); + } + + if (safevalue == "") + { + safevalue = "(empty)"; + } + + return safevalue; +} + +//---------------------------------------------------------------------- void cmCTest::StartXML(std::ostream& ostr, bool append) { if(this->CurrentTag.empty()) @@ -1450,19 +1491,27 @@ void cmCTest::StartXML(std::ostream& ostr, bool append) " NightlStartTime was not set correctly." << std::endl); cmSystemTools::SetFatalErrorOccured(); } + // find out about the system cmsys::SystemInformation info; info.RunCPUCheck(); info.RunOSCheck(); info.RunMemoryCheck(); + + std::string buildname = cmCTest::SafeBuildIdField( + this->GetCTestConfiguration("BuildName")); + std::string stamp = cmCTest::SafeBuildIdField( + this->CurrentTag + "-" + this->GetTestModelString()); + std::string site = cmCTest::SafeBuildIdField( + this->GetCTestConfiguration("Site")); + ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - << "<Site BuildName=\"" << this->GetCTestConfiguration("BuildName") - << "\"\n\tBuildStamp=\"" << this->CurrentTag << "-" - << this->GetTestModelString() << "\"\n\tName=\"" - << this->GetCTestConfiguration("Site") << "\"\n\tGenerator=\"ctest-" - << cmVersion::GetCMakeVersion() << "\"\n" + << "<Site BuildName=\"" << buildname << "\"\n" + << "\tBuildStamp=\"" << stamp << "\"\n" + << "\tName=\"" << site << "\"\n" + << "\tGenerator=\"ctest-" << cmVersion::GetCMakeVersion() << "\"\n" << (append? "\tAppend=\"true\"\n":"") - << "\tCompilerName=\"" << this->GetCTestConfiguration("Compiler") + << "\tCompilerName=\"" << this->GetCTestConfiguration("Compiler") << "\"\n" #ifdef _COMPILER_VERSION << "\tCompilerVersion=\"_COMPILER_VERSION\"\n" diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 44a5349..7c71b00 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -259,6 +259,10 @@ public: std::string* stdOut, std::string* stdErr, int* retVal = 0, const char* dir = 0, double timeout = 0.0); + //! Clean/make safe for xml the given value such that it may be used as + // one of the key fields by CDash when computing the buildid. + static std::string SafeBuildIdField(const std::string& value); + //! Start CTest XML output file void StartXML(std::ostream& ostr, bool append); diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index c1327fb..ea98326 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -65,6 +65,12 @@ bool cmConfigureFileCommand cmSystemTools::SetFatalErrorOccured(); return false; } + std::string errorMessage; + if (!this->NewLineStyle.ReadFromArguments(args, errorMessage)) + { + this->SetError(errorMessage.c_str()); + return false; + } this->CopyOnly = false; this->EscapeQuotes = false; @@ -78,6 +84,12 @@ bool cmConfigureFileCommand if(args[i] == "COPYONLY") { this->CopyOnly = true; + if (this->NewLineStyle.IsValid()) + { + this->SetError("COPYONLY could not be used in combination " + "with NEWLINE_STYLE"); + return false; + } } else if(args[i] == "ESCAPE_QUOTES") { @@ -122,7 +134,8 @@ int cmConfigureFileCommand::ConfigureFile() this->OutputFile.c_str(), this->CopyOnly, this->AtOnly, - this->EscapeQuotes); + this->EscapeQuotes, + this->NewLineStyle); } diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h index 844a23c..be33569 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -56,7 +56,8 @@ public: { return " configure_file(<input> <output>\n" - " [COPYONLY] [ESCAPE_QUOTES] [@ONLY])\n" + " [COPYONLY] [ESCAPE_QUOTES] [@ONLY] \n" + " [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])\n" "Copies a file <input> to file <output> and substitutes variable " "values referenced in the file content. " "If <input> is a relative path it is evaluated with respect to " @@ -81,14 +82,20 @@ public: "either #define VAR or /* #undef VAR */ depending on " "the setting of VAR in CMake. Any occurrences of #cmakedefine01 VAR " "will be replaced with either #define VAR 1 or #define VAR 0 " - "depending on whether VAR evaluates to TRUE or FALSE in CMake"; + "depending on whether VAR evaluates to TRUE or FALSE in CMake.\n" + "With NEWLINE_STYLE the line ending could be adjusted: \n" + " 'UNIX' or 'LF' for \\n, 'DOS', 'WIN32' or 'CRLF' for \\r\\n.\n" + "COPYONLY must not be used with NEWLINE_STYLE.\n"; } virtual void FinalPass(); virtual bool HasFinalPass() const { return !this->Immediate; } + private: int ConfigureFile(); + cmNewLineStyle NewLineStyle; + std::string InputFile; std::string OutputFile; bool CopyOnly; diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx new file mode 100644 index 0000000..a1505bd --- /dev/null +++ b/Source/cmCryptoHash.cxx @@ -0,0 +1,130 @@ +/*============================================================================ + 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 "cmCryptoHash.h" + +#include <cmsys/MD5.h> +#include "cm_sha2.h" + +//---------------------------------------------------------------------------- +cmsys::auto_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo) +{ + if(strcmp(algo,"MD5") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashMD5); } + else if(strcmp(algo,"SHA1") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA1); } + else if(strcmp(algo,"SHA224") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA224); } + else if(strcmp(algo,"SHA256") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA256); } + else if(strcmp(algo,"SHA384") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA384); } + else if(strcmp(algo,"SHA512") == 0) + { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA512); } + else + { return cmsys::auto_ptr<cmCryptoHash>(0); } +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashString(const char* input) +{ + this->Initialize(); + this->Append(reinterpret_cast<unsigned char const*>(input), + static_cast<int>(strlen(input))); + return this->Finalize(); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashFile(const char* file) +{ + std::ifstream fin(file, std::ios::in | cmsys_ios_binary); + if(!fin) + { + return ""; + } + + this->Initialize(); + + // Should be efficient enough on most system: + const int bufferSize = 4096; + char buffer[bufferSize]; + unsigned char const* buffer_uc = + reinterpret_cast<unsigned char const*>(buffer); + // This copy loop is very sensitive on certain platforms with + // slightly broken stream libraries (like HPUX). Normally, it is + // incorrect to not check the error condition on the fin.read() + // before using the data, but the fin.gcount() will be zero if an + // error occurred. Therefore, the loop should be safe everywhere. + while(fin) + { + fin.read(buffer, bufferSize); + if(int gcount = static_cast<int>(fin.gcount())) + { + this->Append(buffer_uc, gcount); + } + } + if(fin.eof()) + { + return this->Finalize(); + } + return ""; +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New()) +{ +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::~cmCryptoHashMD5() +{ + cmsysMD5_Delete(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Initialize() +{ + cmsysMD5_Initialize(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Append(unsigned char const* buf, int sz) +{ + cmsysMD5_Append(this->MD5, buf, sz); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHashMD5::Finalize() +{ + char md5out[32]; + cmsysMD5_FinalizeHex(this->MD5, md5out); + return std::string(md5out, 32); +} + + +#define cmCryptoHash_SHA_CLASS_IMPL(SHA) \ +cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \ +cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \ +void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \ +void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \ +{ SHA##_Update(this->SHA, buf, sz); } \ +std::string cmCryptoHash##SHA::Finalize() \ +{ \ + char out[SHA##_DIGEST_STRING_LENGTH]; \ + SHA##_End(this->SHA, out); \ + return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \ +} + +cmCryptoHash_SHA_CLASS_IMPL(SHA1) +cmCryptoHash_SHA_CLASS_IMPL(SHA224) +cmCryptoHash_SHA_CLASS_IMPL(SHA256) +cmCryptoHash_SHA_CLASS_IMPL(SHA384) +cmCryptoHash_SHA_CLASS_IMPL(SHA512) diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h new file mode 100644 index 0000000..1bea9ab --- /dev/null +++ b/Source/cmCryptoHash.h @@ -0,0 +1,65 @@ +/*============================================================================ + 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 cmCryptoHash_h +#define cmCryptoHash_h + +#include "cmStandardIncludes.h" + +#include <cmsys/auto_ptr.hxx> + +class cmCryptoHash +{ +public: + virtual ~cmCryptoHash() {} + static cmsys::auto_ptr<cmCryptoHash> New(const char* algo); + std::string HashString(const char* input); + std::string HashFile(const char* file); +protected: + virtual void Initialize()=0; + virtual void Append(unsigned char const*, int)=0; + virtual std::string Finalize()=0; +}; + +class cmCryptoHashMD5: public cmCryptoHash +{ + struct cmsysMD5_s* MD5; +public: + cmCryptoHashMD5(); + ~cmCryptoHashMD5(); +protected: + virtual void Initialize(); + virtual void Append(unsigned char const* buf, int sz); + virtual std::string Finalize(); +}; + +#define cmCryptoHash_SHA_CLASS_DECL(SHA) \ + class cmCryptoHash##SHA: public cmCryptoHash \ + { \ + union _SHA_CTX* SHA; \ + public: \ + cmCryptoHash##SHA(); \ + ~cmCryptoHash##SHA(); \ + protected: \ + virtual void Initialize(); \ + virtual void Append(unsigned char const* buf, int sz); \ + virtual std::string Finalize(); \ + } + +cmCryptoHash_SHA_CLASS_DECL(SHA1); +cmCryptoHash_SHA_CLASS_DECL(SHA224); +cmCryptoHash_SHA_CLASS_DECL(SHA256); +cmCryptoHash_SHA_CLASS_DECL(SHA384); +cmCryptoHash_SHA_CLASS_DECL(SHA512); + +#undef cmCryptoHash_SHA_CLASS_DECL + +#endif diff --git a/Source/cmDocumentLocationUndefined.h b/Source/cmDocumentLocationUndefined.h new file mode 100644 index 0000000..d1be77a --- /dev/null +++ b/Source/cmDocumentLocationUndefined.h @@ -0,0 +1,24 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 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 cmDocumentLocationUndefined_h +#define cmDocumentLocationUndefined_h + +#define CM_LOCATION_UNDEFINED_BEHAVIOR(action) \ + "\n" \ + "Do not set properties that affect the location of a target after " \ + action ". These include properties whose names match " \ + "\"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?\" " \ + "or \"(IMPLIB_)?(PREFIX|SUFFIX)\". " \ + "Failure to follow this rule is not diagnosed and leaves the location " \ + "of the target undefined." + +#endif diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index ed303c9..a0632a2 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -508,6 +508,20 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables That Change Behavior"); cm->DefineProperty + ("CMAKE_AUTOMOC_STRICT_MODE", cmProperty::VARIABLE, + "Switch between strict and relaxed automoc mode.", + "When TRUE, automoc behaves exactly as described in the documentation " + "of the AUTOMOC target property. " + "When set to FALSE, it accepts more input and tries to find the correct " + "input file for moc even if it differs from the documented behaviour. " + "In this mode it e.g. also checks whether a header file is intended to " + "be processed by moc when a \"foo.moc\" file has been included.\n" + "When using Qt4, CMAKE_AUTOMOC_STRICT_MODE is initialized to FALSE. " + "It also has to be set to FALSE for KDE4 compatibility.", + false, + "Variables That Change Behavior"); + + cm->DefineProperty ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE, "Prefixes to prepend when looking for libraries.", "This specifies what prefixes to add to library names when " @@ -1112,6 +1126,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_GNUtoMS", cmProperty::VARIABLE, + "Convert GNU import libraries (.dll.a) to MS format (.lib).", + "This variable is used to initialize the GNUtoMS property on targets " + "when they are created. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE, "See variable CMAKE_<CONFIG>_POSTFIX.", "This variable is a special case of the more-general " @@ -1515,6 +1538,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_COMPILER_ID_RUN", cmProperty::VARIABLE,0,0); + cm->DefineProperty("CMAKE_<LANG>_ABI_FILES", + cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_CREATE_ASSEMBLY_SOURCE", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_CREATE_PREPROCESSED_SOURCE", diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 7e73e36..32595ee 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -125,6 +125,8 @@ cmExportBuildFileGenerator std::string prop = "IMPORTED_IMPLIB"; prop += suffix; std::string value = target->GetFullPath(config, true); + target->GetImplibGNUtoMS(value, value, + "${CMAKE_IMPORT_LIBRARY_SUFFIX}"); properties[prop] = value; } } diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index f33e9e2..eb19d2e 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -13,6 +13,7 @@ #define cmExportCommand_h #include "cmCommand.h" +#include "cmDocumentLocationUndefined.h" class cmExportBuildFileGenerator; @@ -80,6 +81,7 @@ public: "should never be installed. " "See the install(EXPORT) command to export targets from an " "installation tree." + CM_LOCATION_UNDEFINED_BEHAVIOR("passing it to this command") "\n" " export(PACKAGE <name>)\n" "Store the current build directory in the CMake user package registry " diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 9e5c91e..c4f5dfb 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -368,3 +368,66 @@ cmExportFileGenerator os << " )\n" << "\n"; } + + +//---------------------------------------------------------------------------- +void +cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) +{ + // Add code which verifies at cmake time that the file which is being + // imported actually exists on disk. This should in theory always be theory + // case, but still when packages are split into normal and development + // packages this might get broken (e.g. the Config.cmake could be part of + // the non-development package, something similar happened to me without + // on SUSE with a mysql pkg-config file, which claimed everything is fine, + // but the development package was not installed.). + os << "# Loop over all imported files and verify that they actually exist\n" + "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n" + " FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n" + " IF(NOT EXISTS \"${file}\" )\n" + " MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\"" + " references the file\n" + " \\\"${file}\\\"\n" + "but this file does not exist. Possible reasons include:\n" + "* The file was deleted, renamed, or moved to another location.\n" + "* An install or uninstall procedure did not complete successfully.\n" + "* The installation package was faulty and contained\n" + " \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n" + "but not all the files it references.\n" + "\")\n" + " ENDIF()\n" + " ENDFOREACH()\n" + " UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n" + "ENDFOREACH()\n" + "UNSET(_IMPORT_CHECK_TARGETS)\n" + "\n"; +} + + +//---------------------------------------------------------------------------- +void +cmExportFileGenerator +::GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target, + ImportPropertyMap const& properties, + const std::set<std::string>& importedLocations) +{ + // Construct the imported target name. + std::string targetName = this->Namespace; + targetName += target->GetName(); + + os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n" + "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " "; + + for(std::set<std::string>::const_iterator li = importedLocations.begin(); + li != importedLocations.end(); + ++li) + { + ImportPropertyMap::const_iterator pi = properties.find(*li); + if (pi != properties.end()) + { + os << "\"" << pi->second << "\" "; + } + } + + os << ")\n\n"; +} diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 05f73a2..f271e55 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -56,6 +56,11 @@ protected: void GenerateImportPropertyCode(std::ostream& os, const char* config, cmTarget* target, ImportPropertyMap const& properties); + void GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target, + ImportPropertyMap const& properties, + const std::set<std::string>& importedLocations); + void GenerateImportedFileCheckLoop(std::ostream& os); + // Collect properties with detailed information about targets beyond // their location on disk. diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 23ff5fb..da14dd7 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -167,16 +167,18 @@ cmExportInstallFileGenerator // Collect import properties for this target. cmTargetExport* te = *tei; ImportPropertyMap properties; + std::set<std::string> importedLocations; + this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator, + properties, importedLocations); + this->SetImportLocationProperty(config, suffix, te->LibraryGenerator, + properties, importedLocations); this->SetImportLocationProperty(config, suffix, - te->ArchiveGenerator, properties); - this->SetImportLocationProperty(config, suffix, - te->LibraryGenerator, properties); - this->SetImportLocationProperty(config, suffix, - te->RuntimeGenerator, properties); - this->SetImportLocationProperty(config, suffix, - te->FrameworkGenerator, properties); - this->SetImportLocationProperty(config, suffix, - te->BundleGenerator, properties); + te->RuntimeGenerator, properties, + importedLocations); + this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator, + properties, importedLocations); + this->SetImportLocationProperty(config, suffix, te->BundleGenerator, + properties, importedLocations); // If any file location was set for the target add it to the // import file. @@ -194,9 +196,13 @@ cmExportInstallFileGenerator // Generate code in the export file. this->GenerateImportPropertyCode(os, config, te->Target, properties); + this->GenerateImportedFileChecksCode(os, te->Target, properties, + importedLocations); } } + this->GenerateImportedFileCheckLoop(os); + // Cleanup the import prefix variable. if(!this->ImportPrefix.empty()) { @@ -211,7 +217,9 @@ void cmExportInstallFileGenerator ::SetImportLocationProperty(const char* config, std::string const& suffix, cmInstallTargetGenerator* itgen, - ImportPropertyMap& properties) + ImportPropertyMap& properties, + std::set<std::string>& importedLocations + ) { // Skip rules that do not match this configuration. if(!(itgen && itgen->InstallsForConfig(config))) @@ -249,6 +257,7 @@ cmExportInstallFileGenerator // Store the property. properties[prop] = value; + importedLocations.insert(prop); } else { @@ -291,6 +300,7 @@ cmExportInstallFileGenerator // Store the property. properties[prop] = value; + importedLocations.insert(prop); } } diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 8c8fb44..fb678e8 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -75,7 +75,9 @@ protected: void SetImportLocationProperty(const char* config, std::string const& suffix, cmInstallTargetGenerator* itgen, - ImportPropertyMap& properties); + ImportPropertyMap& properties, + std::set<std::string>& importedLocations + ); void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 248a30a..07549e9 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -85,7 +85,16 @@ void cmExtraEclipseCDT4Generator::Generate() this->IsOutOfSourceBuild = (this->HomeDirectory!=this->HomeOutputDirectory); this->GenerateSourceProject = (this->IsOutOfSourceBuild && - mf->IsOn("ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT")); + mf->IsOn("CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT")); + + if ((this->GenerateSourceProject == false) + && (mf->IsOn("ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT"))) + { + mf->IssueMessage(cmake::WARNING, + "ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT is set to TRUE, " + "but this variable is not supported anymore since CMake 2.8.7.\n" + "Enable CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT instead."); + } if (cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(), this->HomeDirectory.c_str())) @@ -113,7 +122,7 @@ void cmExtraEclipseCDT4Generator::Generate() this->CreateCProjectFile(); } -void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() const +void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() { assert(this->HomeDirectory != this->HomeOutputDirectory); @@ -141,6 +150,16 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() const "\t</buildSpec>\n" "\t<natures>\n" "\t</natures>\n" + "\t<linkedResources>\n"; + + if (this->SupportsVirtualFolders) + { + this->CreateLinksToSubprojects(fout, this->HomeDirectory); + this->SrcLinkedResources.clear(); + } + + fout << + "\t</linkedResources>\n" "</projectDescription>\n" ; } @@ -434,7 +453,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() if (this->SupportsVirtualFolders) { - this->CreateLinksToSubprojects(fout); + this->CreateLinksToSubprojects(fout, this->HomeOutputDirectory); this->CreateLinksForTargets(fout); } @@ -541,7 +560,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets( //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects( - cmGeneratedFileStream& fout) + cmGeneratedFileStream& fout, const std::string& baseDir) { // for each sub project create a linked resource to the source dir // - only if it is an out-of-source build @@ -557,8 +576,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects( it->second[0]->GetMakefile()->GetStartDirectory()); // a linked resource must not point to a parent directory of .project or // .project itself - if ((this->HomeOutputDirectory != linkSourceDirectory) && - !cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(), + if ((baseDir != linkSourceDirectory) && + !cmSystemTools::IsSubDirectory(baseDir.c_str(), linkSourceDirectory.c_str())) { std::string linkName = "[Subprojects]/"; diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index 61302e7..ebd8c08 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -46,7 +46,7 @@ public: private: // create .project file in the source tree - void CreateSourceProjectFile() const; + void CreateSourceProjectFile(); // create .project file void CreateProjectFile(); @@ -104,7 +104,8 @@ private: static void AddEnvVar(cmGeneratedFileStream& fout, const char* envVar, cmMakefile* mf); - void CreateLinksToSubprojects(cmGeneratedFileStream& fout); + void CreateLinksToSubprojects(cmGeneratedFileStream& fout, + const std::string& baseDir); void CreateLinksForTargets(cmGeneratedFileStream& fout); std::vector<std::string> SrcLinkedResources; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index f933666..6df5ab3 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -13,6 +13,7 @@ #include "cmake.h" #include "cmHexFileConverter.h" #include "cmFileTimeComparison.h" +#include "cmCryptoHash.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cm_curl.h" @@ -22,6 +23,7 @@ #include <sys/types.h> #include <sys/stat.h> +#include <cmsys/auto_ptr.hxx> #include <cmsys/Directory.hxx> #include <cmsys/Glob.hxx> #include <cmsys/RegularExpression.hxx> @@ -83,6 +85,15 @@ bool cmFileCommand { return this->HandleReadCommand(args); } + else if ( subCommand == "MD5" || + subCommand == "SHA1" || + subCommand == "SHA224" || + subCommand == "SHA256" || + subCommand == "SHA384" || + subCommand == "SHA512" ) + { + return this->HandleHashCommand(args); + } else if ( subCommand == "STRINGS" ) { return this->HandleStringsCommand(args); @@ -339,6 +350,41 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) } //---------------------------------------------------------------------------- +bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args) +{ +#if defined(CMAKE_BUILD_WITH_CMAKE) + if(args.size() != 3) + { + cmOStringStream e; + e << args[0] << " requires a file name and output variable"; + this->SetError(e.str().c_str()); + return false; + } + + cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str())); + if(hash.get()) + { + std::string out = hash->HashFile(args[1].c_str()); + if(!out.empty()) + { + this->Makefile->AddDefinition(args[2].c_str(), out.c_str()); + return true; + } + cmOStringStream e; + e << args[0] << " failed to read file \"" << args[1] << "\": " + << cmSystemTools::GetLastSystemError(); + this->SetError(e.str().c_str()); + } + return false; +#else + cmOStringStream e; + e << args[0] << " not available during bootstrap"; + this->SetError(e.str().c_str()); + return false; +#endif +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) { if(args.size() < 3) diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 162890a..9e2ed0f 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -65,6 +65,7 @@ public: " file(WRITE filename \"message to write\"... )\n" " file(APPEND filename \"message to write\"... )\n" " file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])\n" + " file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filename variable)\n" " file(STRINGS filename variable [LIMIT_COUNT num]\n" " [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]\n" " [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]\n" @@ -94,6 +95,8 @@ public: "variable. It will start at the given offset and read up to numBytes. " "If the argument HEX is given, the binary data will be converted to " "hexadecimal representation and this will be stored in the variable.\n" + "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 " + "will compute a cryptographic hash of the content of a file.\n" "STRINGS will parse a list of ASCII strings from a file and " "store it in a variable. Binary data in the file are ignored. Carriage " "return (CR) characters are ignored. It works also for Intel Hex and " @@ -227,6 +230,7 @@ protected: bool HandleRemove(std::vector<std::string> const& args, bool recurse); bool HandleWriteCommand(std::vector<std::string> const& args, bool append); bool HandleReadCommand(std::vector<std::string> const& args); + bool HandleHashCommand(std::vector<std::string> const& args); bool HandleStringsCommand(std::vector<std::string> const& args); bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse); bool HandleMakeDirectoryCommand(std::vector<std::string> const& args); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 32eaef8..859503f 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -458,8 +458,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( std::vector<std::string>::iterator new_end = std::unique(lfiles.begin(), lfiles.end()); lfiles.erase(new_end, lfiles.end()); - std::string dir = mf->GetHomeOutputDirectory(); - this->CurrentReRunCMakeMakefile = dir; + this->CurrentReRunCMakeMakefile = mf->GetStartOutputDirectory(); this->CurrentReRunCMakeMakefile += "/CMakeScripts"; cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str()); this->CurrentReRunCMakeMakefile += "/ReRunCMake.make"; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 33ffbfb..ac1c949 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -101,6 +101,13 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, std::string to1 = toDir + targetNameImport; filesFrom.push_back(from1); filesTo.push_back(to1); + std::string targetNameImportLib; + if(this->Target->GetImplibGNUtoMS(targetNameImport, + targetNameImportLib)) + { + filesFrom.push_back(fromDirConfig + targetNameImportLib); + filesTo.push_back(toDir + targetNameImportLib); + } // An import library looks like a static library. type = cmTarget::STATIC_LIBRARY; @@ -157,6 +164,13 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, std::string to1 = toDir + targetNameImport; filesFrom.push_back(from1); filesTo.push_back(to1); + std::string targetNameImportLib; + if(this->Target->GetImplibGNUtoMS(targetNameImport, + targetNameImportLib)) + { + filesFrom.push_back(fromDirConfig + targetNameImportLib); + filesTo.push_back(toDir + targetNameImportLib); + } // An import library looks like a static library. type = cmTarget::STATIC_LIBRARY; @@ -314,7 +328,11 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target, if(nameType == NameImplib) { // Use the import library name. - fname = targetNameImport; + if(!target->GetImplibGNUtoMS(targetNameImport, fname, + "${CMAKE_IMPORT_LIBRARY_SUFFIX}")) + { + fname = targetNameImport; + } } else if(nameType == NameReal) { @@ -339,7 +357,11 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target, if(nameType == NameImplib) { // Use the import library name. - fname = targetNameImport; + if(!target->GetImplibGNUtoMS(targetNameImport, fname, + "${CMAKE_IMPORT_LIBRARY_SUFFIX}")) + { + fname = targetNameImport; + } } else if(nameType == NameSO) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 65d6fa6..ffbeb48 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -96,14 +96,14 @@ void cmLocalGenerator::Configure() std::string filesDir = this->Makefile->GetStartOutputDirectory(); filesDir += cmake::GetCMakeFilesDirectory(); cmSystemTools::MakeDirectory(filesDir.c_str()); - + // find & read the list file this->ReadInputFile(); // at the end of the ReadListFile handle any old style subdirs // first get all the subdirectories std::vector<cmLocalGenerator *> subdirs = this->GetChildren(); - + // for each subdir recurse std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin(); for (; sdi != subdirs.end(); ++sdi) @@ -112,7 +112,7 @@ void cmLocalGenerator::Configure() { this->Makefile->ConfigureSubDirectory(*sdi); } - } + } // Check whether relative paths should be used for optionally // relative paths. @@ -212,10 +212,10 @@ void cmLocalGenerator::ReadInputFile() } void cmLocalGenerator::SetupPathConversions() -{ +{ // Setup the current output directory components for use by // Convert - std::string outdir; + std::string outdir; outdir = cmSystemTools::CollapseFullPath(this->Makefile->GetHomeDirectory()); cmSystemTools::SplitPath(outdir.c_str(), this->HomeDirectoryComponents); @@ -225,12 +225,12 @@ void cmLocalGenerator::SetupPathConversions() outdir = cmSystemTools::CollapseFullPath (this->Makefile->GetHomeOutputDirectory()); - cmSystemTools::SplitPath(outdir.c_str(), + cmSystemTools::SplitPath(outdir.c_str(), this->HomeOutputDirectoryComponents); outdir = cmSystemTools::CollapseFullPath (this->Makefile->GetStartOutputDirectory()); - cmSystemTools::SplitPath(outdir.c_str(), + cmSystemTools::SplitPath(outdir.c_str(), this->StartOutputDirectoryComponents); } @@ -289,17 +289,17 @@ void cmLocalGenerator::GenerateTestFiles() fout.SetCopyIfDifferent(true); fout << "# CMake generated Testfile for " << std::endl - << "# Source directory: " + << "# Source directory: " << this->Makefile->GetStartDirectory() << std::endl - << "# Build directory: " + << "# Build directory: " << this->Makefile->GetStartOutputDirectory() << std::endl << "# " << std::endl << "# This file includes the relevent testing commands " << "required for " << std::endl << "# testing this directory and lists subdirectories to " << "be tested as well." << std::endl; - - const char* testIncludeFile = + + const char* testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE"); if ( testIncludeFile ) { @@ -320,7 +320,7 @@ void cmLocalGenerator::GenerateTestFiles() for(i = 0; i < this->Children.size(); ++i) { fout << "SUBDIRS("; - std::string outP = + std::string outP = this->Children[i]->GetMakefile()->GetStartOutputDirectory(); fout << this->Convert(outP.c_str(),START_OUTPUT); fout << ")" << std::endl; @@ -472,7 +472,7 @@ void cmLocalGenerator::GenerateInstallRules() // Ask each install generator to write its code. std::vector<cmInstallGenerator*> const& installers = this->Makefile->GetInstallGenerators(); - for(std::vector<cmInstallGenerator*>::const_iterator + for(std::vector<cmInstallGenerator*>::const_iterator gi = installers.begin(); gi != installers.end(); ++gi) { @@ -553,15 +553,15 @@ void cmLocalGenerator::GenerateTargetManifest() } } -void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, - const char* lang, +void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, + const char* lang, cmSourceFile& source, cmTarget& ) -{ +{ std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname)); objectDir = this->Convert(objectDir.c_str(),START_OUTPUT,SHELL); std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL); - std::string sourceFile = + std::string sourceFile = this->Convert(source.GetFullPath().c_str(),START_OUTPUT,SHELL,true); std::string varString = "CMAKE_"; varString += lang; @@ -655,7 +655,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) ofname += "/"; ofname += obj; objVector.push_back(ofname); - this->AddCustomCommandToCreateObject(ofname.c_str(), + this->AddCustomCommandToCreateObject(ofname.c_str(), llang, *(*i), target); objs += this->Convert(ofname.c_str(),START_OUTPUT,MAKEFILE); objs += " "; @@ -672,7 +672,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) // Shared Module: std::string linkLibs; // should be set std::string flags; // should be set - std::string linkFlags; // should be set + std::string linkFlags; // should be set this->GetTargetFlags(linkLibs, flags, linkFlags, target); cmLocalGenerator::RuleVariables vars; vars.Language = llang; @@ -682,17 +682,17 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); - + std::string langFlags; this->AddLanguageFlags(langFlags, llang, 0); this->AddArchitectureFlags(langFlags, &target, llang, 0); vars.LanguageCompileFlags = langFlags.c_str(); - + cmCustomCommandLines commandLines; std::vector<std::string> rules; rules.push_back(this->Makefile->GetRequiredDefinition(createRule.c_str())); std::vector<std::string> commands; - cmSystemTools::ExpandList(rules, commands); + cmSystemTools::ExpandList(rules, commands); for(std::vector<std::string>::iterator i = commands.begin(); i != commands.end(); ++i) { @@ -728,21 +728,21 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) (this->Makefile->GetSource(targetFullPath.c_str())); } - + void cmLocalGenerator ::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang) -{ +{ cmTargets &tgts = this->Makefile->GetTargets(); - for(cmTargets::iterator l = tgts.begin(); + for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { cmTarget& target = l->second; switch(target.GetType()) - { + { case cmTarget::STATIC_LIBRARY: case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: - case cmTarget::EXECUTABLE: + case cmTarget::EXECUTABLE: { const char* llang = target.GetLinkerLanguage(); if(!llang) @@ -759,7 +759,7 @@ void cmLocalGenerator this->AddBuildTargetRule(llang, target); } } - break; + break; default: break; } @@ -769,14 +769,14 @@ void cmLocalGenerator // List of variables that are replaced when // rules are expanced. These variables are // replaced in the form <var> with GetSafeDefinition(var). -// ${LANG} is replaced in the variable first with all enabled +// ${LANG} is replaced in the variable first with all enabled // languages. static const char* ruleReplaceVars[] = { "CMAKE_${LANG}_COMPILER", "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS", "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS", - "CMAKE_SHARED_MODULE_${LANG}_FLAGS", + "CMAKE_SHARED_MODULE_${LANG}_FLAGS", "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS", "CMAKE_${LANG}_LINK_FLAGS", "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG", @@ -807,7 +807,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, return replaceValues.Flags; } } - + if(replaceValues.Source) { if(variable == "SOURCE") @@ -870,7 +870,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, } if(replaceValues.Target) - { + { if(variable == "TARGET_QUOTED") { std::string targetQuoted = replaceValues.Target; @@ -1018,13 +1018,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, int pos = 0; while(ruleReplaceVars[pos]) { - for(std::vector<std::string>::iterator i = enabledLanguages.begin(); - i != enabledLanguages.end(); ++i) - { + for(std::vector<std::string>::iterator i = enabledLanguages.begin(); + i != enabledLanguages.end(); ++i) + { const char* lang = i->c_str(); std::string actualReplace = ruleReplaceVars[pos]; // If this is the compiler then look for the extra variable - // _COMPILER_ARG1 which must be the first argument to the compiler + // _COMPILER_ARG1 which must be the first argument to the compiler const char* compilerArg1 = 0; if(actualReplace == "CMAKE_${LANG}_COMPILER") { @@ -1038,7 +1038,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, } if(actualReplace == variable) { - std::string replace = + std::string replace = this->Makefile->GetSafeDefinition(variable.c_str()); // if the variable is not a FLAG then treat it like a path if(variable.find("_FLAG") == variable.npos) @@ -1062,7 +1062,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, } -void +void cmLocalGenerator::ExpandRuleVariables(std::string& s, const RuleVariables& replaceValues) { @@ -1213,7 +1213,7 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang, std::string flagVar = "CMAKE_INCLUDE_FLAG_"; flagVar += lang; - const char* includeFlag = + const char* includeFlag = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagVar = "CMAKE_INCLUDE_FLAG_SEP_"; flagVar += lang; @@ -1223,7 +1223,7 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang, { quotePaths = true; } - bool repeatFlag = true; + bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB if(!sep) { @@ -1354,15 +1354,15 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, this->Makefile->GetDefinition("VTK_SOURCE_DIR"); if(vtkSourceDir) { - const char* vtk_major = + const char* vtk_major = this->Makefile->GetDefinition("VTK_MAJOR_VERSION"); - const char* vtk_minor = + const char* vtk_minor = this->Makefile->GetDefinition("VTK_MINOR_VERSION"); vtk_major = vtk_major? vtk_major : "4"; vtk_minor = vtk_minor? vtk_minor : "4"; int vmajor = 0; int vminor = 0; - if(sscanf(vtk_major, "%d", &vmajor) && + if(sscanf(vtk_major, "%d", &vmajor) && sscanf(vtk_minor, "%d", &vminor) && vmajor == 4 && vminor <= 4) { includeSourceDir = true; @@ -1403,7 +1403,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } // Get the project-specified include directories. - std::vector<std::string>& includes = + std::vector<std::string>& includes = this->Makefile->GetIncludeDirectories(); // Support putting all the in-project include directories first if @@ -1446,17 +1446,17 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, std::string& linkFlags, cmTarget& target) { - std::string buildType = + std::string buildType = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - buildType = cmSystemTools::UpperCase(buildType); - const char* libraryLinkVariable = + buildType = cmSystemTools::UpperCase(buildType); + const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library - + switch(target.GetType()) { - case cmTarget::STATIC_LIBRARY: + case cmTarget::STATIC_LIBRARY: { - const char* targetLinkFlags = + const char* targetLinkFlags = target.GetProperty("STATIC_LIBRARY_FLAGS"); if(targetLinkFlags) { @@ -1475,11 +1475,11 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } } - break; + break; case cmTarget::MODULE_LIBRARY: libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS"; case cmTarget::SHARED_LIBRARY: - { + { linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable); linkFlags += " "; if(!buildType.empty()) @@ -1489,8 +1489,8 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, build += buildType; linkFlags += this->Makefile->GetSafeDefinition(build.c_str()); linkFlags += " "; - } - if(this->Makefile->IsOn("WIN32") && + } + if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW"))) { const std::vector<cmSourceFile*>& sources = target.GetSourceFiles(); @@ -1500,14 +1500,14 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, cmSourceFile* sf = *i; if(sf->GetExtension() == "def") { - linkFlags += + linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); linkFlags += this->Convert(sf->GetFullPath().c_str(), START_OUTPUT, SHELL); linkFlags += " "; } } - } + } const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); if(targetLinkFlags) { @@ -1520,11 +1520,11 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, configLinkFlags += buildType; targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) - { + { linkFlags += targetLinkFlags; linkFlags += " "; } - } + } cmOStringStream linklibsStr; this->OutputLinkLibraries(linklibsStr, target, false); linkLibs = linklibsStr.str(); @@ -1532,7 +1532,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, break; case cmTarget::EXECUTABLE: { - linkFlags += + linkFlags += this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS"); linkFlags += " "; if(!buildType.empty()) @@ -1541,7 +1541,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, build += buildType; linkFlags += this->Makefile->GetSafeDefinition(build.c_str()); linkFlags += " "; - } + } const char* linkLanguage = target.GetLinkerLanguage(); if(!linkLanguage) { @@ -1566,7 +1566,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, if(cmSystemTools::IsOn (this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { - std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage + std::string("_FLAGS"); linkFlags += this->Makefile->GetSafeDefinition(sFlagVar.c_str()); linkFlags += " "; @@ -1579,7 +1579,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } else { - linkFlags += + linkFlags += this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); linkFlags += " "; } @@ -1595,13 +1595,13 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, configLinkFlags += buildType; targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) - { + { linkFlags += targetLinkFlags; linkFlags += " "; } } } - break; + break; default: break; } @@ -1661,9 +1661,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, const char* linkLanguage = cli.GetLinkLanguage(); - std::string libPathFlag = + std::string libPathFlag = this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG"); - std::string libPathTerminator = + std::string libPathTerminator = this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR"); // Flags to link an executable to shared libraries. @@ -1786,11 +1786,11 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, { std::vector<std::string> archs; target->GetAppleArchs(config, archs); - const char* sysroot = + const char* sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); - const char* sysrootDefault = + const char* sysrootDefault = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT"); - const char* deploymentTarget = + const char* deploymentTarget = this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); std::string isysrootVar = std::string("CMAKE_") + lang + "_HAS_ISYSROOT"; bool hasIsysroot = this->Makefile->IsOn(isysrootVar.c_str()); @@ -1876,7 +1876,7 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, if(cmSystemTools::FileIsFullPath(inName)) { std::string tLocation; - if(target->GetType() >= cmTarget::EXECUTABLE && + if(target->GetType() >= cmTarget::EXECUTABLE && target->GetType() <= cmTarget::MODULE_LIBRARY) { tLocation = target->GetLocation(config); @@ -2904,7 +2904,7 @@ std::string cmLocalGenerator::EscapeForShell(const char* str, bool makeVars, else { cmsysSystem_Shell_GetArgumentForUnix(str, &arg[0], flags); - } + } return std::string(&arg[0]); } @@ -2976,9 +2976,9 @@ cmLocalGenerator::GetTargetDirectory(cmTarget const&) const //---------------------------------------------------------------------------- -void +void cmLocalGenerator::GetTargetObjectFileDirectories(cmTarget* , - std::vector<std::string>& + std::vector<std::string>& ) { cmSystemTools::Error("GetTargetObjectFileDirectories" diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 4d16409..de1ac30 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -250,6 +250,20 @@ cmLocalVisualStudioGenerator // Add this command line. std::string cmd = ccg.GetCommand(c); + + // Use "call " before any invocations of .bat or .cmd files + // invoked as custom commands. + // + std::string suffix; + if (cmd.size() > 4) + { + suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size()-4)); + if (suffix == ".bat" || suffix == ".cmd") + { + script += "call "; + } + } + script += this->Convert(cmd.c_str(), relativeRoot, SHELL); ccg.AppendArguments(c, script); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 573c430..7939d73 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3213,7 +3213,8 @@ void cmMakefile::ConfigureString(const std::string& input, } int cmMakefile::ConfigureFile(const char* infile, const char* outfile, - bool copyonly, bool atOnly, bool escapeQuotes) + bool copyonly, bool atOnly, bool escapeQuotes, + const cmNewLineStyle& newLine) { int res = 1; if ( !this->CanIWriteThisFile(outfile) ) @@ -3250,9 +3251,20 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, } else { + std::string newLineCharacters; + std::ios_base::openmode omode = std::ios_base::out | std::ios_base::trunc; + if (newLine.IsValid()) + { + newLineCharacters = newLine.GetCharacters(); + omode |= std::ios::binary; + } + else + { + newLineCharacters = "\n"; + } std::string tempOutputFile = soutfile; tempOutputFile += ".tmp"; - std::ofstream fout(tempOutputFile.c_str()); + std::ofstream fout(tempOutputFile.c_str(), omode); if(!fout) { cmSystemTools::Error( @@ -3277,7 +3289,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, { outLine = ""; this->ConfigureString(inLine, outLine, atOnly, escapeQuotes); - fout << outLine.c_str() << "\n"; + fout << outLine.c_str() << newLineCharacters; } // close the files before attempting to copy fin.close(); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 7c3e4ee..1236787 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -19,6 +19,7 @@ #include "cmPropertyMap.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmNewLineStyle.h" #include "cmake.h" #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -703,7 +704,9 @@ public: * Copy file but change lines acording to ConfigureString */ int ConfigureFile(const char* infile, const char* outfile, - bool copyonly, bool atOnly, bool escapeQuotes); + bool copyonly, bool atOnly, bool escapeQuotes, + const cmNewLineStyle& = cmNewLineStyle()); + #if defined(CMAKE_BUILD_WITH_CMAKE) /** diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index cd75d79..78278cb 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -241,6 +241,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) exeCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(), cmLocalGenerator::START_OUTPUT, cmLocalGenerator::UNCHANGED)); + std::string implib; + if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib)) + { + exeCleanFiles.push_back(this->Convert(implib.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED)); + } } // List the PDB for cleaning only when the whole target is @@ -270,8 +277,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string linkRuleVar = "CMAKE_"; linkRuleVar += linkLanguage; linkRuleVar += "_LINK_EXECUTABLE"; - std::string linkRule = - this->Makefile->GetRequiredDefinition(linkRuleVar.c_str()); + std::string linkRule = this->GetLinkRule(linkRuleVar.c_str()); std::vector<std::string> commands1; cmSystemTools::ExpandListArgument(linkRule, real_link_commands); if(this->Target->IsExecutableWithExports()) diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 31f7be5..b4174cc 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -512,6 +512,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(), cmLocalGenerator::START_OUTPUT, cmLocalGenerator::UNCHANGED)); + std::string implib; + if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib)) + { + libCleanFiles.push_back(this->Convert(implib.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED)); + } } // List the PDB for cleaning only when the whole target is @@ -772,7 +779,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules else { // Get the set of commands. - std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar); + std::string linkRule = this->GetLinkRule(linkRuleVar); cmSystemTools::ExpandListArgument(linkRule, real_link_commands); // Expand placeholders. diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 8b91194..a3a832b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1634,6 +1634,23 @@ void cmMakefileTargetGenerator } //---------------------------------------------------------------------------- +std::string cmMakefileTargetGenerator::GetLinkRule(const char* linkRuleVar) +{ + std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar); + if(this->Target->HasImplibGNUtoMS()) + { + std::string ruleVar = "CMAKE_"; + ruleVar += this->Target->GetLinkerLanguage(this->ConfigName); + ruleVar += "_GNUtoMS_RULE"; + if(const char* rule = this->Makefile->GetDefinition(ruleVar.c_str())) + { + linkRule += rule; + } + } + return linkRule; +} + +//---------------------------------------------------------------------------- void cmMakefileTargetGenerator ::CloseFileStreams() { diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 674cd13..8fba13f 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -120,6 +120,9 @@ protected: // Append link rule dependencies (objects, etc.). void AppendLinkDepends(std::vector<std::string>& depends); + // Lookup the link rule for this target. + std::string GetLinkRule(const char* linkRuleVar); + /** In order to support parallel builds for custom commands with multiple outputs the outputs are given a serial order, and only the first output actually has the build rule. Other outputs diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx new file mode 100644 index 0000000..6f7b6a9 --- /dev/null +++ b/Source/cmNewLineStyle.cxx @@ -0,0 +1,95 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 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 "cmNewLineStyle.h" + + + +cmNewLineStyle::cmNewLineStyle() : NewLineStyle(Invalid) +{ +} + + +bool cmNewLineStyle::IsValid() const +{ + return NewLineStyle != Invalid; +} + + +bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, + std::string& errorString) +{ + NewLineStyle = Invalid; + + for (size_t i = 0; i< args.size(); i++) + { + if (args[i] == "NEWLINE_STYLE") + { + size_t const styleIndex = i + 1; + if (args.size() > styleIndex) + { + const std::string eol = args[styleIndex]; + if (eol == "LF" || eol == "UNIX") + { + NewLineStyle = LF; + return true; + } + else if (eol == "CRLF" || eol == "WIN32" || eol == "DOS") + { + NewLineStyle = CRLF; + return true; + } + else + { + errorString = "NEWLINE_STYLE sets an unknown style, only LF, " + "CRLF, UNIX, DOS, and WIN32 are supported"; + return false; + } + } + else + { + errorString = "NEWLINE_STYLE must set a style: " + "LF, CRLF, UNIX, DOS, or WIN32"; + return false; + } + } + } + return true; +} + + +const std::string cmNewLineStyle::GetCharacters() const +{ + switch (NewLineStyle) + { + case Invalid: + return ""; + case LF: + return "\n"; + case CRLF: + return "\r\n"; + default: + ; + }; + return ""; +} + + +void cmNewLineStyle::SetStyle(Style style) +{ + NewLineStyle = style; +} + + +cmNewLineStyle::Style cmNewLineStyle::GetStyle() const +{ + return NewLineStyle; +} diff --git a/Source/cmNewLineStyle.h b/Source/cmNewLineStyle.h new file mode 100644 index 0000000..cae1106 --- /dev/null +++ b/Source/cmNewLineStyle.h @@ -0,0 +1,46 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 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 cmNewLineStyle_h +#define cmNewLineStyle_h + +#include "cmStandardIncludes.h" + +class cmNewLineStyle +{ +public: + + cmNewLineStyle(); + + enum Style + { + Invalid, + // LF = '\n', 0x0A, 10 + // CR = '\r', 0x0D, 13 + LF, // Unix + CRLF // Dos + }; + + void SetStyle(Style); + Style GetStyle() const; + + bool IsValid() const; + + bool ReadFromArguments(const std::vector<std::string>& args, + std::string &errorString); + + const std::string GetCharacters() const; + +private: + Style NewLineStyle; +}; + +#endif diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index ae63701..65c7952 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -17,11 +17,70 @@ #include "cmSourceFile.h" #include "cmSystemTools.h" -# include <cmsys/Terminal.h> +#include <cmsys/Terminal.h> + +#include <string.h> #include "cmQtAutomoc.h" +static bool containsQ_OBJECT(const std::string& text) +{ + // this simple check is much much faster than the regexp + if (strstr(text.c_str(), "Q_OBJECT") == NULL) + { + return false; + } + + cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + return qObjectRegExp.find(text); +} + + +static std::string findMatchingHeader(const std::string& absPath, + const std::string& mocSubDir, + const std::string& basename, + const std::list<std::string>& headerExtensions) +{ + std::string header; + for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + std::string sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + header = sourceFilePath; + break; + } + if (!mocSubDir.empty()) + { + sourceFilePath = mocSubDir + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + header = sourceFilePath; + break; + } + } + } + + return header; +} + + +static std::string extractSubDir(const std::string& absPath, + const std::string& currentMoc) +{ + std::string subDir; + if (currentMoc.find_first_of('/') != std::string::npos) + { + subDir = absPath + + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/'; + } + return subDir; +} + + cmQtAutomoc::cmQtAutomoc() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,ColorOutput(true) @@ -49,13 +108,23 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); const char* targetName = target->GetName(); - // don't do anything if there is no Qt4: + // don't do anything if there is no Qt4 or Qt5Core (which contains moc): std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); + if (qtMajorVersion == "") + { + qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR"); + } if (qtMajorVersion != "4" && qtMajorVersion != "5") { return; } + bool strictMode = (qtMajorVersion == "5"); + if (makefile->IsDefinitionSet("CMAKE_AUTOMOC_STRICT_MODE")) + { + strictMode = makefile->IsOn("CMAKE_AUTOMOC_STRICT_MODE"); + } + // create a custom target for running automoc at buildtime: std::string automocTargetName = targetName; automocTargetName += "_automoc"; @@ -144,6 +213,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) makefile->AddDefinition("_moc_options", _moc_options.c_str()); makefile->AddDefinition("_moc_files", _moc_files.c_str()); makefile->AddDefinition("_moc_headers", _moc_headers.c_str()); + makefile->AddDefinition("_moc_strict_mode", strictMode ? "TRUE" : "FALSE"); const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); std::string inputFile = cmakeRoot; @@ -179,7 +249,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - this->RunAutomocQt4(); + this->RunAutomoc(); } this->WriteOldMocDefinitionsFile(targetDirectory); @@ -222,6 +292,11 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, } this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); + if (this->QtMajorVersion == "") + { + this->QtMajorVersion = makefile->GetSafeDefinition( + "AM_Qt5Core_VERSION_MAJOR"); + } this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); this->Headers = makefile->GetSafeDefinition("AM_HEADERS"); this->IncludeProjectDirsBefore = makefile->IsOn( @@ -238,6 +313,8 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + this->StrictMode = makefile->IsOn("AM_STRICT_MODE"); + return true; } @@ -382,7 +459,7 @@ void cmQtAutomoc::Init() } -bool cmQtAutomoc::RunAutomocQt4() +bool cmQtAutomoc::RunAutomoc() { if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' '))) @@ -406,6 +483,23 @@ bool cmQtAutomoc::RunAutomocQt4() std::vector<std::string> sourceFiles; cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); + std::list<std::string> headerExtensions; + headerExtensions.push_back(".h"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); +#if defined(_WIN32) + // not case sensitive, don't add ".H" +#elif defined(__APPLE__) + // detect case-sensitive filesystem + long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); + if (caseSensitive == 1) + { + headerExtensions.push_back(".H"); + } +#else + headerExtensions.push_back(".H"); +#endif + for (std::vector<std::string>::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) @@ -415,7 +509,15 @@ bool cmQtAutomoc::RunAutomocQt4() { std::cout << "AUTOMOC: Checking " << absFilename << std::endl; } - this->ParseCppFile(absFilename, includedMocs, headerFiles); + if (this->StrictMode == false) + { + this->ParseCppFile(absFilename, headerExtensions, includedMocs); + } + else + { + this->StrictParseCppFile(absFilename, headerExtensions, includedMocs); + } + this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles); } std::vector<std::string> headerFilesVec; @@ -496,40 +598,37 @@ bool cmQtAutomoc::RunAutomocQt4() void cmQtAutomoc::ParseCppFile(const std::string& absFilename, - std::map<std::string, std::string>& includedMocs, - std::set<std::string>& absHeaders) + const std::list<std::string>& headerExtensions, + std::map<std::string, std::string>& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); - std::list<std::string> headerExtensions; - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); -#if defined(_WIN32) - // not case sensitive, don't add ".H" -#elif defined(__APPLE__) - // detect case-sensitive filesystem - long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); - if (caseSensitive == 1) - { - headerExtensions.push_back(".H"); - } -#else - headerExtensions.push_back(".H"); -#endif const std::string contentsString = this->ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOMOC: empty source file: " << absFilename << std::endl; + std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + << std::endl; return; } const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + const std::string scannedFileBasename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename); + const bool cppContainsQ_OBJECT = containsQ_OBJECT(contentsString); + bool dotMocIncluded = false; + bool mocUnderscoreIncluded = false; + std::string ownMocUnderscoreFile; + std::string ownDotMocFile; + std::string ownMocHeaderFile; std::string::size_type matchOffset = 0; - if (mocIncludeRegExp.find(contentsString.c_str())) + // first a simply string check for "moc" is *much* faster than the regexp, + // and if the string search already fails, we don't have to try the + // expensive regexp + if ((strstr(contentsString.c_str(), "moc") != NULL) + && (mocIncludeRegExp.find(contentsString))) { // for every moc include in the file do @@ -552,78 +651,248 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, // basename should be the part of the moc filename used for // finding the correct header, so we need to remove the moc_ part basename = basename.substr(4); + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); - bool headerFound = false; - for(std::list<std::string>::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + if (!headerToMoc.empty()) + { + includedMocs[headerToMoc] = currentMoc; + if (basename == scannedFileBasename) + { + mocUnderscoreIncluded = true; + ownMocUnderscoreFile = currentMoc; + ownMocHeaderFile = headerToMoc; + } + } + else { - const std::string &sourceFilePath = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + std::cerr << "AUTOMOC: error: " << absFilename << " The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->Join(headerExtensions, ',') << "}\" "; + if (mocSubDir.empty()) { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - break; + std::cerr << "in " << absPath << "\n" << std::endl; } + else + { + std::cerr << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; + } + + ::exit(EXIT_FAILURE); } - if (!headerFound) + } + else + { + std::string fileToMoc = absFilename; + if ((basename != scannedFileBasename) || (cppContainsQ_OBJECT==false)) { - // the moc file is in a subdir => look for the header in the - // same subdir - if (currentMoc.find_first_of('/') != std::string::npos) + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); + if (!headerToMoc.empty()) { - const std::string &filepath = absPath - + cmsys::SystemTools::GetFilenamePath(currentMoc) - + '/' + basename; - - for(std::list<std::string>::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + // this is for KDE4 compatibility: + fileToMoc = headerToMoc; + if ((cppContainsQ_OBJECT==false) &&(basename==scannedFileBasename)) { - const std::string &sourceFilePath = filepath + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) - { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - break; - } + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", but does not contain a Q_OBJECT macro. " + "Running moc on " + << "\"" << headerToMoc << "\" ! Better include \"moc_" + << basename << ".cpp\" for a robust build.\n" + << std::endl; } - if (!headerFound) + else { - std::cerr << "AUTOMOC: The file \"" << absFilename - << "\" includes the moc file \"" << currentMoc - << "\", but neither \"" << absPath << basename - << '{' << this->Join(headerExtensions, ',') - << "}\" nor \"" << filepath << '{' - << this->Join(headerExtensions, ',') << '}' - << "\" exist." << std::endl; - ::exit(EXIT_FAILURE); + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\" instead of \"moc_" << basename << ".cpp\". " + "Running moc on " + << "\"" << headerToMoc << "\" ! Better include \"moc_" + << basename << ".cpp\" for a robust build.\n" + << std::endl; } } else { - std::cerr << "AUTOMOC: The file \"" << absFilename - << "\" includes the moc file \"" << currentMoc - << "\", but \"" << absPath << basename << '{' - << this->Join(headerExtensions, ',') << '}' - << "\" does not exist." << std::endl; + std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. CMake also could not find a matching " + "header.\n" << std::endl; ::exit(EXIT_FAILURE); } } + else + { + dotMocIncluded = true; + ownDotMocFile = currentMoc; + } + includedMocs[fileToMoc] = currentMoc; + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } + + // In this case, check whether the scanned file itself contains a Q_OBJECT. + // If this is the case, the moc_foo.cpp should probably be generated from + // foo.cpp instead of foo.h, because otherwise it won't build. + // But warn, since this is not how it is supposed to be used. + if ((dotMocIncluded == false) && (cppContainsQ_OBJECT == true)) + { + if (mocUnderscoreIncluded == true) + { + // this is for KDE4 compatibility: + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\", but instead " + "includes " + << "\"" << ownMocUnderscoreFile << "\". Running moc on " + << "\"" << absFilename << "\" ! Better include \"" + << scannedFileBasename << ".moc\" for a robust build.\n" + << std::endl; + includedMocs[absFilename] = ownMocUnderscoreFile; + includedMocs.erase(ownMocHeaderFile); + } + else + { + // otherwise always error out since it will not compile: + std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + ::exit(EXIT_FAILURE); + } + } + +} + + +void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, + const std::list<std::string>& headerExtensions, + std::map<std::string, std::string>& includedMocs) +{ + cmsys::RegularExpression mocIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); + + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) + { + std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + << std::endl; + return; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + const std::string scannedFileBasename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename); + + bool dotMocIncluded = false; + + std::string::size_type matchOffset = 0; + // first a simply string check for "moc" is *much* faster than the regexp, + // and if the string search already fails, we don't have to try the + // expensive regexp + if ((strstr(contentsString.c_str(), "moc") != NULL) + && (mocIncludeRegExp.find(contentsString))) + { + // for every moc include in the file + do + { + const std::string currentMoc = mocIncludeRegExp.match(1); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool mocUnderscoreStyle = this->StartsWith(basename, "moc_"); + + // If the moc include is of the moc_foo.cpp style we expect + // the Q_OBJECT class declaration in a header file. + // If the moc include is of the foo.moc style we need to look for + // a Q_OBJECT macro in the current source file, if it contains the + // macro we generate the moc file from the source file. + if (mocUnderscoreStyle) + { + // basename should be the part of the moc filename used for + // finding the correct header, so we need to remove the moc_ part + basename = basename.substr(4); + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); + + if (!headerToMoc.empty()) + { + includedMocs[headerToMoc] = currentMoc; + } + else + { + std::cerr << "AUTOMOC: error: " << absFilename << " The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->Join(headerExtensions, ',') << "}\" "; + if (mocSubDir.empty()) + { + std::cerr << "in " << absPath << "\n" << std::endl; + } + else + { + std::cerr << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; + } + + ::exit(EXIT_FAILURE); + } } else { + if (basename != scannedFileBasename) + { + std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. This is not supported. " + "Include \"" << scannedFileBasename << ".moc\" to run " + "moc on this source file.\n" << std::endl; + ::exit(EXIT_FAILURE); + } + dotMocIncluded = true; includedMocs[absFilename] = currentMoc; } matchOffset += mocIncludeRegExp.end(); } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); } + // In this case, check whether the scanned file itself contains a Q_OBJECT. + // If this is the case, the moc_foo.cpp should probably be generated from + // foo.cpp instead of foo.h, because otherwise it won't build. + // But warn, since this is not how it is supposed to be used. + if ((dotMocIncluded == false) && (containsQ_OBJECT(contentsString))) + { + // otherwise always error out since it will not compile: + std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + ::exit(EXIT_FAILURE); + } + +} + + +void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, + const std::list<std::string>& headerExtensions, + std::set<std::string>& absHeaders) +{ // search for header files and private header files we may need to moc: const std::string basename = cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) @@ -654,7 +923,6 @@ void cmQtAutomoc::ParseHeaders(const std::set<std::string>& absHeaders, const std::map<std::string, std::string>& includedMocs, std::map<std::string, std::string>& notIncludedMocs) { - cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); for(std::set<std::string>::const_iterator hIt=absHeaders.begin(); hIt!=absHeaders.end(); ++hIt) @@ -673,7 +941,7 @@ void cmQtAutomoc::ParseHeaders(const std::set<std::string>& absHeaders, const std::string currentMoc = "moc_" + basename + ".cpp"; const std::string contents = this->ReadAll(headerName); - if (qObjectRegExp.find(contents)) + if (containsQ_OBJECT(contents)) { //std::cout << "header contains Q_OBJECT macro"; notIncludedMocs[headerName] = currentMoc; @@ -750,7 +1018,7 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); if (!result || retVal) { - std::cerr << "AUTOMOC: process for " << mocFilePath << " failed:\n" + std::cerr << "AUTOMOC: error: process for " << mocFilePath <<" failed:\n" << output << std::endl; this->RunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath.c_str()); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index db53b21..a31f36a 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -35,12 +35,19 @@ private: const char* targetDirectory); void WriteOldMocDefinitionsFile(const char* targetDirectory); - bool RunAutomocQt4(); + bool RunAutomoc(); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); void ParseCppFile(const std::string& absFilename, - std::map<std::string, std::string>& includedMocs, - std::set<std::string>& absHeaders); + const std::list<std::string>& headerExtensions, + std::map<std::string, std::string>& includedMocs); + void StrictParseCppFile(const std::string& absFilename, + const std::list<std::string>& headerExtensions, + std::map<std::string, std::string>& includedMocs); + void SearchHeadersForCppFile(const std::string& absFilename, + const std::list<std::string>& headerExtensions, + std::set<std::string>& absHeaders); + void ParseHeaders(const std::set<std::string>& absHeaders, const std::map<std::string, std::string>& includedMocs, std::map<std::string, std::string>& notIncludedMocs); @@ -78,6 +85,7 @@ private: bool ColorOutput; bool RunMocFailed; bool GenerateAll; + bool StrictMode; }; diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index e8decbb..ea299ca 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -161,6 +161,11 @@ extern int putenv (char *__string) __THROW; #define for if(false) {} else for #endif +// Provide std::ios_base on ancient GCC 2.9x +#if defined(__GNUC__) && __GNUC__ < 3 +namespace std { typedef ios ios_base; } +#endif + // check for the 720 compiler on the SGI // which has some strange properties that I don't think are worth // checking for in a general way in configure diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index d239c06..ec10d57 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -10,6 +10,8 @@ See the License for more information. ============================================================================*/ #include "cmStringCommand.h" +#include "cmCryptoHash.h" + #include <cmsys/RegularExpression.hxx> #include <cmsys/SystemTools.hxx> @@ -36,6 +38,15 @@ bool cmStringCommand { return this->HandleReplaceCommand(args); } + else if ( subCommand == "MD5" || + subCommand == "SHA1" || + subCommand == "SHA224" || + subCommand == "SHA256" || + subCommand == "SHA384" || + subCommand == "SHA512" ) + { + return this->HandleHashCommand(args); + } else if(subCommand == "TOLOWER") { return this->HandleToUpperLowerCommand(args, false); @@ -83,6 +94,34 @@ bool cmStringCommand } //---------------------------------------------------------------------------- +bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args) +{ +#if defined(CMAKE_BUILD_WITH_CMAKE) + if(args.size() != 3) + { + cmOStringStream e; + e << args[0] << " requires an output variable and an input string"; + this->SetError(e.str().c_str()); + return false; + } + + cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str())); + if(hash.get()) + { + std::string out = hash->HashString(args[2].c_str()); + this->Makefile->AddDefinition(args[1].c_str(), out.c_str()); + return true; + } + return false; +#else + cmOStringStream e; + e << args[0] << " not available during bootstrap"; + this->SetError(e.str().c_str()); + return false; +#endif +} + +//---------------------------------------------------------------------------- bool cmStringCommand::HandleToUpperLowerCommand( std::vector<std::string> const& args, bool toUpper) { diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 52b83d9..452f4a1 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -76,6 +76,8 @@ public: " string(REPLACE <match_string>\n" " <replace_string> <output variable>\n" " <input> [<input>...])\n" + " string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>\n" + " <output variable> <input>)\n" " string(COMPARE EQUAL <string1> <string2> <output variable>)\n" " string(COMPARE NOTEQUAL <string1> <string2> <output variable>)\n" " string(COMPARE LESS <string1> <string2> <output variable>)\n" @@ -103,6 +105,8 @@ public: "backslash through argument parsing.\n" "REPLACE will replace all occurrences of match_string in the input with " "replace_string and store the result in the output.\n" + "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 " + "will compute a cryptographic hash of the input string.\n" "COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and " "store true or false in the output variable.\n" "ASCII will convert all numbers into corresponding ASCII characters.\n" @@ -150,6 +154,7 @@ protected: bool RegexMatch(std::vector<std::string> const& args); bool RegexMatchAll(std::vector<std::string> const& args); bool RegexReplace(std::vector<std::string> const& args); + bool HandleHashCommand(std::vector<std::string> const& args); bool HandleToUpperLowerCommand(std::vector<std::string> const& args, bool toUpper); bool HandleCompareCommand(std::vector<std::string> const& args); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 03364bd..8eec1e2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -54,7 +54,7 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) # include <memory> // auto_ptr # include <fcntl.h> -# include <cmsys/MD5.h> +# include "cmCryptoHash.h" #endif #if defined(CMAKE_USE_ELF_PARSER) @@ -1197,48 +1197,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname) bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) { #if defined(CMAKE_BUILD_WITH_CMAKE) - if(!cmSystemTools::FileExists(source)) - { - return false; - } - - // Open files -#if defined(_WIN32) || defined(__CYGWIN__) - cmsys_ios::ifstream fin(source, cmsys_ios::ios::binary | cmsys_ios::ios::in); -#else - cmsys_ios::ifstream fin(source); -#endif - if(!fin) - { - return false; - } - - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - - // Should be efficient enough on most system: - const int bufferSize = 4096; - char buffer[bufferSize]; - unsigned char const* buffer_uc = - reinterpret_cast<unsigned char const*>(buffer); - // This copy loop is very sensitive on certain platforms with - // slightly broken stream libraries (like HPUX). Normally, it is - // incorrect to not check the error condition on the fin.read() - // before using the data, but the fin.gcount() will be zero if an - // error occurred. Therefore, the loop should be safe everywhere. - while(fin) - { - fin.read(buffer, bufferSize); - if(int gcount = static_cast<int>(fin.gcount())) - { - cmsysMD5_Append(md5, buffer_uc, gcount); - } - } - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - - fin.close(); - return true; + cmCryptoHashMD5 md5; + std::string str = md5.HashFile(source); + strncpy(md5out, str.c_str(), 32); + return !str.empty(); #else (void)source; (void)md5out; @@ -1250,13 +1212,8 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) std::string cmSystemTools::ComputeStringMD5(const char* input) { #if defined(CMAKE_BUILD_WITH_CMAKE) - char md5out[32]; - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1); - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - return std::string(md5out, 32); + cmCryptoHashMD5 md5; + return md5.HashString(input); #else (void)input; cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error"); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index dad0353..fc3c1c9 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -17,6 +17,7 @@ #include "cmGlobalGenerator.h" #include "cmComputeLinkInformation.h" #include "cmDocumentCompileDefinitions.h" +#include "cmDocumentLocationUndefined.h" #include "cmListFileCache.h" #include "cmGeneratorExpression.h" #include <cmsys/RegularExpression.hxx> @@ -131,6 +132,7 @@ cmTarget::cmTarget() this->LinkLibrariesAnalyzed = false; this->HaveInstallRule = false; this->DLLPlatform = false; + this->IsApple = false; this->IsImportedTarget = false; } @@ -159,8 +161,10 @@ void cmTarget::DefineProperties(cmake *cm) "This property is initialized by the value of the variable " "CMAKE_AUTOMOC if it is set when a target is created.\n" "Additional command line options for moc can be set via the " - "AUTOMOC_MOC_OPTIONS property." - ); + "AUTOMOC_MOC_OPTIONS property.\n" + "By setting the CMAKE_AUTOMOC_STRICT_MODE variable to FALSE the rules " + "for searching the files which will be processed by moc can be relaxed. " + "See the documentation for this variable for more details."); cm->DefineProperty ("AUTOMOC_MOC_OPTIONS", cmProperty::TARGET, @@ -584,15 +588,6 @@ void cmTarget::DefineProperties(cmake *cm) "value is the default. " "See documentation of CMAKE_<LANG>_LINKER_PREFERENCE variables."); -#define CM_LOCATION_UNDEFINED_BEHAVIOR \ - "\n" \ - "Do not set properties that affect the location of the target after " \ - "reading this property. These include properties whose names match " \ - "\"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?\" " \ - "or \"(IMPLIB_)?(PREFIX|SUFFIX)\". " \ - "Failure to follow this rule is not diagnosed and leaves the location " \ - "of the target undefined." - cm->DefineProperty ("LOCATION", cmProperty::TARGET, "Read-only location of a target on disk.", @@ -612,7 +607,7 @@ void cmTarget::DefineProperties(cmake *cm) "In CMake 2.8.4 and above add_custom_command recognizes generator " "expressions to refer to target locations anywhere in the command. " "Therefore this property is not needed for creating custom commands." - CM_LOCATION_UNDEFINED_BEHAVIOR); + CM_LOCATION_UNDEFINED_BEHAVIOR("reading this property")); cm->DefineProperty ("LOCATION_<CONFIG>", cmProperty::TARGET, @@ -626,7 +621,7 @@ void cmTarget::DefineProperties(cmake *cm) "arbitrary available configuration. " "Use the MAP_IMPORTED_CONFIG_<CONFIG> property to map imported " "configurations explicitly." - CM_LOCATION_UNDEFINED_BEHAVIOR); + CM_LOCATION_UNDEFINED_BEHAVIOR("reading this property")); cm->DefineProperty ("LINK_DEPENDS", cmProperty::TARGET, @@ -980,6 +975,23 @@ void cmTarget::DefineProperties(cmake *cm) "is created its value is used to initialize this property."); cm->DefineProperty + ("GNUtoMS", cmProperty::TARGET, + "Convert GNU import library (.dll.a) to MS format (.lib).", + "When linking a shared library or executable that exports symbols " + "using GNU tools on Windows (MinGW/MSYS) with Visual Studio installed " + "convert the import library (.dll.a) from GNU to MS format (.lib). " + "Both import libraries will be installed by install(TARGETS) and " + "exported by install(EXPORT) and export() to be linked by applications " + "with either GNU- or MS-compatible tools." + "\n" + "If the variable CMAKE_GNUtoMS is set when a target " + "is created its value is used to initialize this property. " + "The variable must be set prior to the first command that enables " + "a language such as project() or enable_language(). " + "CMake provides the variable as an option to the user automatically " + "when configuring on Windows with GNU tools."); + + cm->DefineProperty ("XCODE_ATTRIBUTE_<an-attribute>", cmProperty::TARGET, "Set Xcode target attributes directly.", "Tell the Xcode generator to set '<an-attribute>' to a given value " @@ -1038,6 +1050,29 @@ void cmTarget::DefineProperties(cmake *cm) "Can be set to change the visual studio source code control " "auxpath property."); cm->DefineProperty + ("VS_GLOBAL_PROJECT_TYPES", cmProperty::TARGET, + "Visual Studio project type(s).", + "Can be set to one or more UUIDs recognized by Visual Studio " + "to indicate the type of project. This value is copied " + "verbatim into the generated project file. Example for a " + "managed C++ unit testing project: \"" + "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};" + "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\". UUIDs are " + "semicolon-delimited."); + cm->DefineProperty + ("VS_GLOBAL_KEYWORD", cmProperty::TARGET, + "Visual Studio project keyword.", + "Sets the \"keyword\" attribute for a generated Visual Studio " + "project. Defaults to \"Win32Proj\". You may wish to override " + "this value with \"ManagedCProj\", for example, in a Visual " + "Studio managed C++ unit test project."); + cm->DefineProperty + ("VS_DOTNET_REFERENCES", cmProperty::TARGET, + "Visual Studio managed project .NET references", + "Adds one or more semicolon-delimited .NET references to a " + "generated Visual Studio project. For example, \"System;" + "System.Windows.Forms\"."); + cm->DefineProperty ("VS_GLOBAL_<variable>", cmProperty::TARGET, "Visual Studio project-specific global variable.", "Tell the Visual Studio generator to set the global variable " @@ -1184,6 +1219,9 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW")); + // Check whether we are targeting an Apple platform. + this->IsApple = this->Makefile->IsOn("APPLE"); + // Setup default property values. this->SetPropertyDefault("INSTALL_NAME_DIR", ""); this->SetPropertyDefault("INSTALL_RPATH", ""); @@ -1195,6 +1233,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); + this->SetPropertyDefault("GNUtoMS", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); this->SetPropertyDefault("AUTOMOC", 0); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); @@ -3325,7 +3364,11 @@ void cmTarget::GetLibraryNames(std::string& name, // the library version as the soversion. soversion = version; } - bool isApple = this->Makefile->IsOn("APPLE"); + if(!version && soversion) + { + // Use the soversion as the library version. + version = soversion; + } // Get the components of the library name. std::string prefix; @@ -3337,47 +3380,12 @@ void cmTarget::GetLibraryNames(std::string& name, name = prefix+base+suffix; // The library's soname. - if(isApple) - { - soName = prefix+base; - } - else - { - soName = name; - } - if(soversion) - { - soName += "."; - soName += soversion; - } - if(isApple) - { - soName += suffix; - } + this->ComputeVersionedName(soName, prefix, base, suffix, + name, soversion); // The library's real name on disk. - if(isApple) - { - realName = prefix+base; - } - else - { - realName = name; - } - if(version) - { - realName += "."; - realName += version; - } - else if(soversion) - { - realName += "."; - realName += soversion; - } - if(isApple) - { - realName += suffix; - } + this->ComputeVersionedName(realName, prefix, base, suffix, + name, version); // The import library name. if(this->GetType() == cmTarget::SHARED_LIBRARY || @@ -3395,6 +3403,23 @@ void cmTarget::GetLibraryNames(std::string& name, } //---------------------------------------------------------------------------- +void cmTarget::ComputeVersionedName(std::string& vName, + std::string const& prefix, + std::string const& base, + std::string const& suffix, + std::string const& name, + const char* version) +{ + vName = this->IsApple? (prefix+base) : name; + if(version) + { + vName += "."; + vName += version; + } + vName += this->IsApple? suffix : std::string(); +} + +//---------------------------------------------------------------------------- void cmTarget::GetExecutableNames(std::string& name, std::string& realName, std::string& impName, @@ -3457,6 +3482,26 @@ void cmTarget::GetExecutableNames(std::string& name, } //---------------------------------------------------------------------------- +bool cmTarget::HasImplibGNUtoMS() +{ + return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS"); +} + +//---------------------------------------------------------------------------- +bool cmTarget::GetImplibGNUtoMS(std::string const& gnuName, + std::string& out, const char* newExt) +{ + if(this->HasImplibGNUtoMS() && + gnuName.size() > 6 && gnuName.substr(gnuName.size()-6) == ".dll.a") + { + out = gnuName.substr(0, gnuName.size()-6); + out += newExt? newExt : ".lib"; + return true; + } + return false; +} + +//---------------------------------------------------------------------------- void cmTarget::GenerateTargetManifest(const char* config) { cmMakefile* mf = this->Makefile; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0abdddb..59f0184 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -369,6 +369,14 @@ public: std::string& impName, std::string& pdbName, const char* config); + /** Does this target have a GNU implib to convert to MS format? */ + bool HasImplibGNUtoMS(); + + /** Convert the given GNU import library name (.dll.a) to a name with a new + extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */ + bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out, + const char* newExt = 0); + /** Add the target output files to the global generator manifest. */ void GenerateTargetManifest(const char* config); @@ -557,6 +565,7 @@ private: cmPropertyMap Properties; LinkLibraryVectorType OriginalLinkLibraries; bool DLLPlatform; + bool IsApple; bool IsImportedTarget; // Cache target output paths for each configuration. @@ -595,6 +604,12 @@ private: cmTargetInternalPointer Internal; void ConstructSourceFileFlags(); + void ComputeVersionedName(std::string& vName, + std::string const& prefix, + std::string const& base, + std::string const& suffix, + std::string const& name, + const char* version); }; typedef std::map<cmStdString,cmTarget> cmTargets; diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 805959d..36c4ca8 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -95,8 +95,8 @@ bool cmTargetLinkLibrariesCommand bool haveLLT = false; // Start with primary linking and switch to link interface - // specification when the keyword is encountered. - this->DoingInterface = false; + // specification if the keyword is encountered as the first argument. + this->CurrentProcessingState = ProcessingLinkLibraries; // add libraries, nothe that there is an optional prefix // of debug and optimized than can be used @@ -104,7 +104,7 @@ bool cmTargetLinkLibrariesCommand { if(args[i] == "LINK_INTERFACE_LIBRARIES") { - this->DoingInterface = true; + this->CurrentProcessingState = ProcessingLinkInterface; if(i != 1) { this->Makefile->IssueMessage( @@ -115,6 +115,32 @@ bool cmTargetLinkLibrariesCommand return true; } } + else if(args[i] == "LINK_PUBLIC") + { + if(i != 1 && this->CurrentProcessingState != ProcessingPrivateInterface) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " + "argument, just after the target name." + ); + return true; + } + this->CurrentProcessingState = ProcessingPublicInterface; + } + else if(args[i] == "LINK_PRIVATE") + { + if(i != 1 && this->CurrentProcessingState != ProcessingPublicInterface) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " + "argument, just after the target name." + ); + return true; + } + this->CurrentProcessingState = ProcessingPrivateInterface; + } else if(args[i] == "debug") { if(haveLLT) @@ -186,10 +212,12 @@ bool cmTargetLinkLibrariesCommand cmSystemTools::SetFatalErrorOccured(); } - // If the INTERFACE option was given, make sure the - // LINK_INTERFACE_LIBRARIES property exists. This allows the - // command to be used to specify an empty link interface. - if(this->DoingInterface && + // If any of the LINK_ options were given, make sure the + // LINK_INTERFACE_LIBRARIES target property exists. + // Use of any of the new keywords implies awareness of + // this property. And if no libraries are named, it should + // result in an empty link interface. + if(this->CurrentProcessingState != ProcessingLinkLibraries && !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) { this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); @@ -217,11 +245,15 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt) { // Handle normal case first. - if(!this->DoingInterface) + if(this->CurrentProcessingState != ProcessingLinkInterface) { this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); - return; + if (this->CurrentProcessingState != ProcessingPublicInterface) + { + // Not LINK_INTERFACE_LIBRARIES or LINK_PUBLIC, do not add to interface. + return; + } } // Get the list of configurations considered to be DEBUG. diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index ce57df7..8df4ac0 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -19,7 +19,7 @@ * * cmTargetLinkLibrariesCommand is used to specify a list of libraries to link * into executable(s) or shared objects. The names of the libraries - * should be those defined by the LIBRARY(library) command(s). + * should be those defined by the LIBRARY(library) command(s). */ class cmTargetLinkLibrariesCommand : public cmCommand { @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmTargetLinkLibrariesCommand; } @@ -47,12 +47,12 @@ public: /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() { - return + return "Link a target to given libraries."; } - + /** * More documentation. */ @@ -107,6 +107,18 @@ public: "Libraries specified as \"general\" (or without any keyword) are " "treated as if specified for both \"debug\" and \"optimized\"." "\n" + " target_link_libraries(<target>\n" + " <LINK_PRIVATE|LINK_PUBLIC>\n" + " [[debug|optimized|general] <lib>] ...\n" + " [<LINK_PRIVATE|LINK_PUBLIC>\n" + " [[debug|optimized|general] <lib>] ...])\n" + "The LINK_PUBLIC and LINK_PRIVATE modes can be used to specify both " + "the link dependencies and the link interface in one command. " + "Libraries and targets following LINK_PUBLIC are linked to, and are " + "made part of the LINK_INTERFACE_LIBRARIES. Libraries and targets " + "following LINK_PRIVATE are linked to, but are not made part of the " + "LINK_INTERFACE_LIBRARIES. " + "\n" "The library dependency graph is normally acyclic (a DAG), but in the " "case of mutually-dependent STATIC libraries CMake allows the graph " "to contain cycles (strongly connected components). " @@ -130,14 +142,21 @@ public: ")" ; } - + cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand); private: void LinkLibraryTypeSpecifierWarning(int left, int right); static const char* LinkLibraryTypeNames[3]; cmTarget* Target; - bool DoingInterface; + enum ProcessingState { + ProcessingLinkLibraries, + ProcessingLinkInterface, + ProcessingPublicInterface, + ProcessingPrivateInterface + }; + + ProcessingState CurrentProcessingState; void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt); }; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 2c9ef37..a219ae9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -178,6 +178,15 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteString("<ProjectGUID>", 2); (*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGUID>\n"; + const char* vsProjectTypes = + this->Target->GetProperty("VS_GLOBAL_PROJECT_TYPES"); + if(vsProjectTypes) + { + this->WriteString("<ProjectTypes>", 2); + (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectTypes) << + "</ProjectTypes>\n"; + } + const char* vsProjectName = this->Target->GetProperty("VS_SCC_PROJECTNAME"); const char* vsLocalPath = this->Target->GetProperty("VS_SCC_LOCALPATH"); const char* vsProvider = this->Target->GetProperty("VS_SCC_PROVIDER"); @@ -203,7 +212,19 @@ void cmVisualStudio10TargetGenerator::Generate() } } - this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2); + const char* vsGlobalKeyword = + this->Target->GetProperty("VS_GLOBAL_KEYWORD"); + if(!vsGlobalKeyword) + { + this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2); + } + else + { + this->WriteString("<Keyword>", 2); + (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalKeyword) << + "</Keyword>\n"; + } + this->WriteString("<Platform>", 2); (*this->BuildFileStream) << this->Platform << "</Platform>\n"; const char* projLabel = this->Target->GetProperty("PROJECT_LABEL"); @@ -233,6 +254,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteCustomCommands(); this->WriteObjSources(); this->WriteCLSources(); + this->WriteDotNetReferences(); this->WriteProjectReferences(); this->WriteString( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\"" @@ -244,6 +266,39 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteGroups(); } +void cmVisualStudio10TargetGenerator::WriteDotNetReferences() +{ + const char* vsDotNetReferences + = this->Target->GetProperty("VS_DOTNET_REFERENCES"); + if(vsDotNetReferences) + { + std::string references(vsDotNetReferences); + std::string::size_type position = 0; + + this->WriteString("<ItemGroup>\n", 1); + while(references.length() > 0) + { + if((position = references.find(";")) == std::string::npos) + { + position = references.length() + 1; + } + + this->WriteString("<Reference Include=\"", 2); + (*this->BuildFileStream) << + cmVS10EscapeXML(references.substr(0, position)) << "\">\n"; + this->WriteString("<CopyLocalSatelliteAssemblies>true" + "</CopyLocalSatelliteAssemblies>\n", 3); + this->WriteString("<ReferenceOutputAssembly>true" + "</ReferenceOutputAssembly>\n", 3); + this->WriteString("</Reference>\n", 2); + + references.erase(0, position + 1); + } + + this->WriteString("</ItemGroup>\n", 1); + } +} + // ConfigurationType Application, Utility StaticLibrary DynamicLibrary void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() @@ -298,16 +353,24 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() } configType += "</ConfigurationType>\n"; this->WriteString(configType.c_str(), 2); + const char* mfcFlag = this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG"); - if(mfcFlag) + std::string mfcFlagValue = mfcFlag ? mfcFlag : "0"; + + std::string useOfMfcValue = "false"; + if(mfcFlagValue == "1") { - this->WriteString("<UseOfMfc>true</UseOfMfc>\n", 2); + useOfMfcValue = "Static"; } - else + else if(mfcFlagValue == "2") { - this->WriteString("<UseOfMfc>false</UseOfMfc>\n", 2); + useOfMfcValue = "Dynamic"; } + std::string mfcLine = "<UseOfMfc>"; + mfcLine += useOfMfcValue + "</UseOfMfc>\n"; + this->WriteString(mfcLine.c_str(), 2); + if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY && this->ClOptions[*i]->UsingUnicode()) { diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index c3c27f4..6702509 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -47,6 +47,7 @@ private: void WriteProjectConfigurations(); void WriteProjectConfigurationValues(); void WriteCLSources(); + void WriteDotNetReferences(); void WriteObjSources(); void WritePathAndIncrementalLinkOptions(); void WriteItemDefinitionGroups(); diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c new file mode 100644 index 0000000..12c39ed --- /dev/null +++ b/Source/cm_sha2.c @@ -0,0 +1,1613 @@ +/* + * FILE: sha2.c + * AUTHOR: Aaron D. Gifford + * http://www.aarongifford.com/computers/sha.html + * + * Copyright (c) 2000-2003, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.c,v 1.4 2004/01/07 22:58:18 adg Exp $ + */ + +#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */ +#include <assert.h> /* assert() */ +#include "cm_sha2.h" /* "sha2.h" -> "cm_sha2.h" renamed for CMake */ + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-224/256/384/512 Machine Architecture Definitions *************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including <sys/types.h> (which in turn includes + * <machine/endian.h> where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +/* CMake modification: use byte order from cmIML. */ +# include "cmIML/ABI.h" +# undef BYTE_ORDER +# undef BIG_ENDIAN +# undef LITTLE_ENDIAN +# define BYTE_ORDER cmIML_ABI_ENDIAN_ID +# define BIG_ENDIAN cmIML_ABI_ENDIAN_ID_BIG +# define LITTLE_ENDIAN cmIML_ABI_ENDIAN_ID_LITTLE +#endif + +/* CMake modification: use types computed in header. */ +typedef cm_sha2_uint8_t sha_byte; /* Exactly 1 byte */ +typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */ +typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */ +#define SHA_UINT32_C(x) cmIML_INT_UINT32_C(x) +#define SHA_UINT64_C(x) cmIML_INT_UINT64_C(x) +#if defined(__BORLANDC__) +# pragma warn -8004 /* variable assigned value that is never used */ +#endif +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wcast-align" +#endif + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & SHA_UINT32_C(0xff00ff00)) >> 8) | \ + ((tmp & SHA_UINT32_C(0x00ff00ff)) << 8); \ +} +#define REVERSE64(w,x) { \ + sha_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & SHA_UINT64_C(0xff00ff00ff00ff00)) >> 8) | \ + ((tmp & SHA_UINT64_C(0x00ff00ff00ff00ff)) << 8); \ + (x) = ((tmp & SHA_UINT64_C(0xffff0000ffff0000)) >> 16) | \ + ((tmp & SHA_UINT64_C(0x0000ffff0000ffff)) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/* + * Macros for copying blocks of memory and for zeroing out ranges + * of memory. Using these macros makes it easy to switch from + * using memset()/memcpy() and using bzero()/bcopy(). + * + * Please define either SHA2_USE_MEMSET_MEMCPY or define + * SHA2_USE_BZERO_BCOPY depending on which function set you + * choose to use: + */ +#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) +/* Default to memset()/memcpy() if no option is specified */ +#define SHA2_USE_MEMSET_MEMCPY 1 +#endif +#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) +/* Abort with an error if BOTH options are defined */ +#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! +#endif + +#ifdef SHA2_USE_MEMSET_MEMCPY +#define MEMSET_BZERO(p,l) memset((p), 0, (l)) +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#endif +#ifdef SHA2_USE_BZERO_BCOPY +#define MEMSET_BZERO(p,l) bzero((p), (l)) +#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) +#endif + + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: In the original SHA-256/384/512 document, the shift-right + * function was named R and the rotate-right function was called S. + * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the + * web.) + * + * The newer NIST FIPS 180-2 document uses a much clearer naming + * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for + * rotate-left. (See: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * on the web.) + * + * WARNING: These macros must be used cautiously, since they reference + * supplied parameters sometimes more than once, and thus could have + * unexpected side-effects if used without taking this into account. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define SHR(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +/* 32-bit Rotate-left (used in SHA-1): */ +#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) + +/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Function used in SHA-1: */ +#define Parity(x,y,z) ((x) ^ (y) ^ (z)) + +/* Four logical functions used in SHA-256: */ +#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) +#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) +#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x))) +#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) +#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) +#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) +#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ + +/* SHA-224 and SHA-256: */ +void SHA256_Internal_Init(SHA_CTX*, const sha_word32*); +void SHA256_Internal_Last(SHA_CTX*); +void SHA256_Internal_Transform(SHA_CTX*, const sha_word32*); + +/* SHA-384 and SHA-512: */ +void SHA512_Internal_Init(SHA_CTX*, const sha_word64*); +void SHA512_Internal_Last(SHA_CTX*); +void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*); + + +/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/ + +/* Hash constant words K for SHA-1: */ +#define K1_0_TO_19 SHA_UINT32_C(0x5a827999) +#define K1_20_TO_39 SHA_UINT32_C(0x6ed9eba1) +#define K1_40_TO_59 SHA_UINT32_C(0x8f1bbcdc) +#define K1_60_TO_79 SHA_UINT32_C(0xca62c1d6) + +/* Initial hash value H for SHA-1: */ +static const sha_word32 sha1_initial_hash_value[5] = { + SHA_UINT32_C(0x67452301), + SHA_UINT32_C(0xefcdab89), + SHA_UINT32_C(0x98badcfe), + SHA_UINT32_C(0x10325476), + SHA_UINT32_C(0xc3d2e1f0) +}; + +/* Hash constant words K for SHA-224 and SHA-256: */ +static const sha_word32 K256[64] = { + SHA_UINT32_C(0x428a2f98), SHA_UINT32_C(0x71374491), + SHA_UINT32_C(0xb5c0fbcf), SHA_UINT32_C(0xe9b5dba5), + SHA_UINT32_C(0x3956c25b), SHA_UINT32_C(0x59f111f1), + SHA_UINT32_C(0x923f82a4), SHA_UINT32_C(0xab1c5ed5), + SHA_UINT32_C(0xd807aa98), SHA_UINT32_C(0x12835b01), + SHA_UINT32_C(0x243185be), SHA_UINT32_C(0x550c7dc3), + SHA_UINT32_C(0x72be5d74), SHA_UINT32_C(0x80deb1fe), + SHA_UINT32_C(0x9bdc06a7), SHA_UINT32_C(0xc19bf174), + SHA_UINT32_C(0xe49b69c1), SHA_UINT32_C(0xefbe4786), + SHA_UINT32_C(0x0fc19dc6), SHA_UINT32_C(0x240ca1cc), + SHA_UINT32_C(0x2de92c6f), SHA_UINT32_C(0x4a7484aa), + SHA_UINT32_C(0x5cb0a9dc), SHA_UINT32_C(0x76f988da), + SHA_UINT32_C(0x983e5152), SHA_UINT32_C(0xa831c66d), + SHA_UINT32_C(0xb00327c8), SHA_UINT32_C(0xbf597fc7), + SHA_UINT32_C(0xc6e00bf3), SHA_UINT32_C(0xd5a79147), + SHA_UINT32_C(0x06ca6351), SHA_UINT32_C(0x14292967), + SHA_UINT32_C(0x27b70a85), SHA_UINT32_C(0x2e1b2138), + SHA_UINT32_C(0x4d2c6dfc), SHA_UINT32_C(0x53380d13), + SHA_UINT32_C(0x650a7354), SHA_UINT32_C(0x766a0abb), + SHA_UINT32_C(0x81c2c92e), SHA_UINT32_C(0x92722c85), + SHA_UINT32_C(0xa2bfe8a1), SHA_UINT32_C(0xa81a664b), + SHA_UINT32_C(0xc24b8b70), SHA_UINT32_C(0xc76c51a3), + SHA_UINT32_C(0xd192e819), SHA_UINT32_C(0xd6990624), + SHA_UINT32_C(0xf40e3585), SHA_UINT32_C(0x106aa070), + SHA_UINT32_C(0x19a4c116), SHA_UINT32_C(0x1e376c08), + SHA_UINT32_C(0x2748774c), SHA_UINT32_C(0x34b0bcb5), + SHA_UINT32_C(0x391c0cb3), SHA_UINT32_C(0x4ed8aa4a), + SHA_UINT32_C(0x5b9cca4f), SHA_UINT32_C(0x682e6ff3), + SHA_UINT32_C(0x748f82ee), SHA_UINT32_C(0x78a5636f), + SHA_UINT32_C(0x84c87814), SHA_UINT32_C(0x8cc70208), + SHA_UINT32_C(0x90befffa), SHA_UINT32_C(0xa4506ceb), + SHA_UINT32_C(0xbef9a3f7), SHA_UINT32_C(0xc67178f2) +}; + +/* Initial hash value H for SHA-224: */ +static const sha_word32 sha224_initial_hash_value[8] = { + SHA_UINT32_C(0xc1059ed8), + SHA_UINT32_C(0x367cd507), + SHA_UINT32_C(0x3070dd17), + SHA_UINT32_C(0xf70e5939), + SHA_UINT32_C(0xffc00b31), + SHA_UINT32_C(0x68581511), + SHA_UINT32_C(0x64f98fa7), + SHA_UINT32_C(0xbefa4fa4) +}; + +/* Initial hash value H for SHA-256: */ +static const sha_word32 sha256_initial_hash_value[8] = { + SHA_UINT32_C(0x6a09e667), + SHA_UINT32_C(0xbb67ae85), + SHA_UINT32_C(0x3c6ef372), + SHA_UINT32_C(0xa54ff53a), + SHA_UINT32_C(0x510e527f), + SHA_UINT32_C(0x9b05688c), + SHA_UINT32_C(0x1f83d9ab), + SHA_UINT32_C(0x5be0cd19) +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +static const sha_word64 K512[80] = { + SHA_UINT64_C(0x428a2f98d728ae22), SHA_UINT64_C(0x7137449123ef65cd), + SHA_UINT64_C(0xb5c0fbcfec4d3b2f), SHA_UINT64_C(0xe9b5dba58189dbbc), + SHA_UINT64_C(0x3956c25bf348b538), SHA_UINT64_C(0x59f111f1b605d019), + SHA_UINT64_C(0x923f82a4af194f9b), SHA_UINT64_C(0xab1c5ed5da6d8118), + SHA_UINT64_C(0xd807aa98a3030242), SHA_UINT64_C(0x12835b0145706fbe), + SHA_UINT64_C(0x243185be4ee4b28c), SHA_UINT64_C(0x550c7dc3d5ffb4e2), + SHA_UINT64_C(0x72be5d74f27b896f), SHA_UINT64_C(0x80deb1fe3b1696b1), + SHA_UINT64_C(0x9bdc06a725c71235), SHA_UINT64_C(0xc19bf174cf692694), + SHA_UINT64_C(0xe49b69c19ef14ad2), SHA_UINT64_C(0xefbe4786384f25e3), + SHA_UINT64_C(0x0fc19dc68b8cd5b5), SHA_UINT64_C(0x240ca1cc77ac9c65), + SHA_UINT64_C(0x2de92c6f592b0275), SHA_UINT64_C(0x4a7484aa6ea6e483), + SHA_UINT64_C(0x5cb0a9dcbd41fbd4), SHA_UINT64_C(0x76f988da831153b5), + SHA_UINT64_C(0x983e5152ee66dfab), SHA_UINT64_C(0xa831c66d2db43210), + SHA_UINT64_C(0xb00327c898fb213f), SHA_UINT64_C(0xbf597fc7beef0ee4), + SHA_UINT64_C(0xc6e00bf33da88fc2), SHA_UINT64_C(0xd5a79147930aa725), + SHA_UINT64_C(0x06ca6351e003826f), SHA_UINT64_C(0x142929670a0e6e70), + SHA_UINT64_C(0x27b70a8546d22ffc), SHA_UINT64_C(0x2e1b21385c26c926), + SHA_UINT64_C(0x4d2c6dfc5ac42aed), SHA_UINT64_C(0x53380d139d95b3df), + SHA_UINT64_C(0x650a73548baf63de), SHA_UINT64_C(0x766a0abb3c77b2a8), + SHA_UINT64_C(0x81c2c92e47edaee6), SHA_UINT64_C(0x92722c851482353b), + SHA_UINT64_C(0xa2bfe8a14cf10364), SHA_UINT64_C(0xa81a664bbc423001), + SHA_UINT64_C(0xc24b8b70d0f89791), SHA_UINT64_C(0xc76c51a30654be30), + SHA_UINT64_C(0xd192e819d6ef5218), SHA_UINT64_C(0xd69906245565a910), + SHA_UINT64_C(0xf40e35855771202a), SHA_UINT64_C(0x106aa07032bbd1b8), + SHA_UINT64_C(0x19a4c116b8d2d0c8), SHA_UINT64_C(0x1e376c085141ab53), + SHA_UINT64_C(0x2748774cdf8eeb99), SHA_UINT64_C(0x34b0bcb5e19b48a8), + SHA_UINT64_C(0x391c0cb3c5c95a63), SHA_UINT64_C(0x4ed8aa4ae3418acb), + SHA_UINT64_C(0x5b9cca4f7763e373), SHA_UINT64_C(0x682e6ff3d6b2b8a3), + SHA_UINT64_C(0x748f82ee5defb2fc), SHA_UINT64_C(0x78a5636f43172f60), + SHA_UINT64_C(0x84c87814a1f0ab72), SHA_UINT64_C(0x8cc702081a6439ec), + SHA_UINT64_C(0x90befffa23631e28), SHA_UINT64_C(0xa4506cebde82bde9), + SHA_UINT64_C(0xbef9a3f7b2c67915), SHA_UINT64_C(0xc67178f2e372532b), + SHA_UINT64_C(0xca273eceea26619c), SHA_UINT64_C(0xd186b8c721c0c207), + SHA_UINT64_C(0xeada7dd6cde0eb1e), SHA_UINT64_C(0xf57d4f7fee6ed178), + SHA_UINT64_C(0x06f067aa72176fba), SHA_UINT64_C(0x0a637dc5a2c898a6), + SHA_UINT64_C(0x113f9804bef90dae), SHA_UINT64_C(0x1b710b35131c471b), + SHA_UINT64_C(0x28db77f523047d84), SHA_UINT64_C(0x32caab7b40c72493), + SHA_UINT64_C(0x3c9ebe0a15c9bebc), SHA_UINT64_C(0x431d67c49c100d4c), + SHA_UINT64_C(0x4cc5d4becb3e42b6), SHA_UINT64_C(0x597f299cfc657e2a), + SHA_UINT64_C(0x5fcb6fab3ad6faec), SHA_UINT64_C(0x6c44198c4a475817) +}; + +/* Initial hash value H for SHA-384 */ +static const sha_word64 sha384_initial_hash_value[8] = { + SHA_UINT64_C(0xcbbb9d5dc1059ed8), + SHA_UINT64_C(0x629a292a367cd507), + SHA_UINT64_C(0x9159015a3070dd17), + SHA_UINT64_C(0x152fecd8f70e5939), + SHA_UINT64_C(0x67332667ffc00b31), + SHA_UINT64_C(0x8eb44a8768581511), + SHA_UINT64_C(0xdb0c2e0d64f98fa7), + SHA_UINT64_C(0x47b5481dbefa4fa4) +}; + +/* Initial hash value H for SHA-512 */ +static const sha_word64 sha512_initial_hash_value[8] = { + SHA_UINT64_C(0x6a09e667f3bcc908), + SHA_UINT64_C(0xbb67ae8584caa73b), + SHA_UINT64_C(0x3c6ef372fe94f82b), + SHA_UINT64_C(0xa54ff53a5f1d36f1), + SHA_UINT64_C(0x510e527fade682d1), + SHA_UINT64_C(0x9b05688c2b3e6c1f), + SHA_UINT64_C(0x1f83d9abfb41bd6b), + SHA_UINT64_C(0x5be0cd19137e2179) +}; + +/* + * Constant used by SHA224/256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha_hex_digits = "0123456789abcdef"; + + +/*** SHA-1: ***********************************************************/ +void SHA1_Init(SHA_CTX* context) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s1.state, sha1_initial_hash_value, sizeof(sha_word32) * 5); + MEMSET_BZERO(context->s1.buffer, 64); + context->s1.bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-1 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + REVERSE32(*data++, W1[j]); \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + W1[j]; \ + (b) = ROTL32(30, (b)); \ + j++; + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + ( W1[j] = *data++ ); \ + (b) = ROTL32(30, (b)); \ + j++; + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_16_TO_19(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_20_TO_39(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_40_TO_59(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_60_TO_79(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e; + sha_word32 T1, *W1; + int j; + + W1 = (sha_word32*)context->s1.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s1.state[0]; + b = context->s1.state[1]; + c = context->s1.state[2]; + d = context->s1.state[3]; + e = context->s1.state[4]; + + j = 0; + + /* Rounds 0 to 15 unrolled: */ + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + + /* Rounds 16 to 19 unrolled: */ + ROUND1_16_TO_19(e,a,b,c,d); + ROUND1_16_TO_19(d,e,a,b,c); + ROUND1_16_TO_19(c,d,e,a,b); + ROUND1_16_TO_19(b,c,d,e,a); + + /* Rounds 20 to 39 unrolled: */ + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + + /* Rounds 40 to 59 unrolled: */ + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + + /* Rounds 60 to 79 unrolled: */ + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + + /* Compute the current intermediate hash value */ + context->s1.state[0] += a; + context->s1.state[1] += b; + context->s1.state[2] += c; + context->s1.state[3] += d; + context->s1.state[4] += e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e; + sha_word32 T1, *W1; + int j; + + W1 = (sha_word32*)context->s1.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s1.state[0]; + b = context->s1.state[1]; + c = context->s1.state[2]; + d = context->s1.state[3]; + e = context->s1.state[4]; + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + T1 = data[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++, W1[j]); + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 16); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 20); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 40); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 60); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 80); + + + /* Compute the current intermediate hash value */ + context->s1.state[0] += a; + context->s1.state[1] += b; + context->s1.state[2] += c; + context->s1.state[3] += d; + context->s1.state[4] += e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + unsigned int freespace, usedspace; + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); + + usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = 64 - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, freespace); + context->s1.bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len); + context->s1.bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= 64) { + /* Process as many complete blocks as we can */ + SHA1_Internal_Transform(context, (sha_word32*)data); + context->s1.bitcount += 512; + len -= 64; + data += 64; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->s1.buffer, data, len); + context->s1.bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA1_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (digest == (sha_byte*)0) { + /* + * No digest buffer, so we can do nothing + * except clean up and go home + */ + MEMSET_BZERO(context, sizeof(*context)); + return; + } + + usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64); + if (usedspace == 0) { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->s1.buffer, 56); + + /* Begin padding with a 1 bit: */ + *context->s1.buffer = 0x80; + } else { + /* Begin padding with a 1 bit: */ + context->s1.buffer[usedspace++] = 0x80; + + if (usedspace <= 56) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->s1.buffer[usedspace], 56 - usedspace); + } else { + if (usedspace < 64) { + MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace); + } + /* Do second-to-last transform: */ + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->s1.buffer, 56); + } + /* Clean up: */ + usedspace = 0; + } + /* Set the bit count: */ +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s1.bitcount,context->s1.bitcount); +#endif + *(sha_word64*)&context->s1.buffer[56] = context->s1.bitcount; + + /* Final transform: */ + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s1.state[j],context->s1.state[j]); + *d++ = context->s1.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s1.state, SHA1_DIGEST_LENGTH); +#endif + + /* Clean up: */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *SHA1_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA1_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA1_Final(digest, context); + + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH); + return buffer; +} + +char* SHA1_Data(const sha_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA1_Init(&context); + SHA1_Update(&context, data, len); + return SHA1_End(&context, digest); +} + + +/*** SHA-256: *********************************************************/ +void SHA256_Internal_Init(SHA_CTX* context, const sha_word32* ihv) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s256.state, ihv, sizeof(sha_word32) * 8); + MEMSET_BZERO(context->s256.buffer, 64); + context->s256.bitcount = 0; +} + +void SHA256_Init(SHA_CTX* context) { + SHA256_Internal_Init(context, sha256_initial_hash_value); +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e, f, g, h, s0, s1; + sha_word32 T1, *W256; + int j; + + W256 = (sha_word32*)context->s256.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s256.state[0]; + b = context->s256.state[1]; + c = context->s256.state[2]; + d = context->s256.state[3]; + e = context->s256.state[4]; + f = context->s256.state[5]; + g = context->s256.state[6]; + h = context->s256.state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->s256.state[0] += a; + context->s256.state[1] += b; + context->s256.state[2] += c; + context->s256.state[3] += d; + context->s256.state[4] += e; + context->s256.state[5] += f; + context->s256.state[6] += g; + context->s256.state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e, f, g, h, s0, s1; + sha_word32 T1, T2, *W256; + int j; + + W256 = (sha_word32*)context->s256.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s256.state[0]; + b = context->s256.state[1]; + c = context->s256.state[2]; + d = context->s256.state[3]; + e = context->s256.state[4]; + f = context->s256.state[5]; + g = context->s256.state[6]; + h = context->s256.state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->s256.state[0] += a; + context->s256.state[1] += b; + context->s256.state[2] += c; + context->s256.state[3] += d; + context->s256.state[4] += e; + context->s256.state[5] += f; + context->s256.state[6] += g; + context->s256.state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); + + usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = 64 - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, freespace); + context->s256.bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len); + context->s256.bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= 64) { + /* Process as many complete blocks as we can */ + SHA256_Internal_Transform(context, (sha_word32*)data); + context->s256.bitcount += 512; + len -= 64; + data += 64; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->s256.buffer, data, len); + context->s256.bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Internal_Last(SHA_CTX* context) { + unsigned int usedspace; + + usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64); +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s256.bitcount,context->s256.bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->s256.buffer[usedspace++] = 0x80; + + if (usedspace <= 56) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->s256.buffer[usedspace], 56 - usedspace); + } else { + if (usedspace < 64) { + MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->s256.buffer, 56); + } + /* Clean up: */ + usedspace = 0; + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->s256.buffer, 56); + + /* Begin padding with a 1 bit: */ + *context->s256.buffer = 0x80; + } + /* Set the bit count: */ + *(sha_word64*)&context->s256.buffer[56] = context->s256.bitcount; + + /* Final transform: */ + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); +} + +void SHA256_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s256.state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *SHA256_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} + + +/*** SHA-224: *********************************************************/ +void SHA224_Init(SHA_CTX* context) { + SHA256_Internal_Init(context, sha224_initial_hash_value); +} + +void SHA224_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + SHA256_Internal_Transform(context, data); +} + +void SHA224_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + SHA256_Update(context, data, len); +} + +void SHA224_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s256.state, SHA224_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *SHA224_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA224_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA224_Final(digest, context); + + for (i = 0; i < SHA224_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH); + return buffer; +} + +char* SHA224_Data(const sha_byte* data, size_t len, char digest[SHA224_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA224_Init(&context); + SHA224_Update(&context, data, len); + return SHA224_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Internal_Init(SHA_CTX* context, const sha_word64* ihv) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s512.state, ihv, sizeof(sha_word64) * 8); + MEMSET_BZERO(context->s512.buffer, 128); + context->s512.bitcount[0] = context->s512.bitcount[1] = 0; +} + +void SHA512_Init(SHA_CTX* context) { + SHA512_Internal_Init(context, sha512_initial_hash_value); +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) { + sha_word64 a, b, c, d, e, f, g, h, s0, s1; + sha_word64 T1, *W512 = (sha_word64*)context->s512.buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->s512.state[0]; + b = context->s512.state[1]; + c = context->s512.state[2]; + d = context->s512.state[3]; + e = context->s512.state[4]; + f = context->s512.state[5]; + g = context->s512.state[6]; + h = context->s512.state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->s512.state[0] += a; + context->s512.state[1] += b; + context->s512.state[2] += c; + context->s512.state[3] += d; + context->s512.state[4] += e; + context->s512.state[5] += f; + context->s512.state[6] += g; + context->s512.state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) { + sha_word64 a, b, c, d, e, f, g, h, s0, s1; + sha_word64 T1, T2, *W512 = (sha_word64*)context->s512.buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->s512.state[0]; + b = context->s512.state[1]; + c = context->s512.state[2]; + d = context->s512.state[3]; + e = context->s512.state[4]; + f = context->s512.state[5]; + g = context->s512.state[6]; + h = context->s512.state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->s512.state[0] += a; + context->s512.state[1] += b; + context->s512.state[2] += c; + context->s512.state[3] += d; + context->s512.state[4] += e; + context->s512.state[5] += f; + context->s512.state[6] += g; + context->s512.state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); + + usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = 128 - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, freespace); + ADDINC128(context->s512.bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len); + ADDINC128(context->s512.bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= 128) { + /* Process as many complete blocks as we can */ + SHA512_Internal_Transform(context, (sha_word64*)data); + ADDINC128(context->s512.bitcount, 1024); + len -= 128; + data += 128; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->s512.buffer, data, len); + ADDINC128(context->s512.bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Internal_Last(SHA_CTX* context) { + unsigned int usedspace; + + usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128); +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]); + REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->s512.buffer[usedspace++] = 0x80; + + if (usedspace <= 112) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->s512.buffer[usedspace], 112 - usedspace); + } else { + if (usedspace < 128) { + MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->s512.buffer, 112); + } + /* Clean up: */ + usedspace = 0; + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->s512.buffer, 112); + + /* Begin padding with a 1 bit: */ + *context->s512.buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha_word64*)&context->s512.buffer[112] = context->s512.bitcount[1]; + *(sha_word64*)&context->s512.buffer[120] = context->s512.bitcount[0]; + + /* Final transform: */ + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); +} + +void SHA512_Final(sha_byte digest[], SHA_CTX* context) { + sha_word64 *d = (sha_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA512_Internal_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s512.state, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *SHA512_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA_CTX* context) { + SHA512_Internal_Init(context, sha384_initial_hash_value); +} + +void SHA384_Update(SHA_CTX* context, const sha_byte* data, size_t len) { + SHA512_Update(context, data, len); +} + +void SHA384_Final(sha_byte digest[], SHA_CTX* context) { + sha_word64 *d = (sha_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA512_Internal_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s512.state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); +} + +char *SHA384_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h new file mode 100644 index 0000000..71395f0 --- /dev/null +++ b/Source/cm_sha2.h @@ -0,0 +1,140 @@ +/* + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford + * http://www.aarongifford.com/computers/sha.html + * + * Copyright (c) 2000-2003, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.h,v 1.4 2004/01/07 19:06:18 adg Exp $ + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#include "cm_sha2_mangle.h" + +/* CMake modification: use integer types from cmIML. */ +#include "cmIML/INT.h" +typedef cmIML_INT_uint8_t cm_sha2_uint8_t; +typedef cmIML_INT_uint32_t cm_sha2_uint32_t; +typedef cmIML_INT_uint64_t cm_sha2_uint64_t; + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Import u_intXX_t size_t type definitions from system headers. You + * may need to change this, or define these things yourself in this + * file. + */ +#include <sys/types.h> + +/*** SHA-224/256/384/512 Various Length Definitions *******************/ + +/* Digest lengths for SHA-1/224/256/384/512 */ +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) +#define SHA224_DIGEST_LENGTH 28 +#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-224/256/384/512 Context Structures ***************************/ + +typedef union _SHA_CTX { + /* SHA-1 uses this part of the union: */ + struct { + cm_sha2_uint32_t state[5]; + cm_sha2_uint64_t bitcount; + cm_sha2_uint8_t buffer[64]; + } s1; + + /* SHA-224 and SHA-256 use this part of the union: */ + struct { + cm_sha2_uint32_t state[8]; + cm_sha2_uint64_t bitcount; + cm_sha2_uint8_t buffer[64]; + } s256; + + /* SHA-384 and SHA-512 use this part of the union: */ + struct { + cm_sha2_uint64_t state[8]; + cm_sha2_uint64_t bitcount[2]; + cm_sha2_uint8_t buffer[128]; + } s512; +} SHA_CTX; + +/*** SHA-256/384/512 Function Prototypes ******************************/ + +void SHA1_Init(SHA_CTX*); +void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); +char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); +char* SHA1_Data(const cm_sha2_uint8_t*, size_t, + char[SHA1_DIGEST_STRING_LENGTH]); + +void SHA224_Init(SHA_CTX*); +void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); +char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); +char* SHA224_Data(const cm_sha2_uint8_t*, size_t, + char[SHA224_DIGEST_STRING_LENGTH]); + +void SHA256_Init(SHA_CTX*); +void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); +char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const cm_sha2_uint8_t*, size_t, + char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA_CTX*); +void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); +char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const cm_sha2_uint8_t*, size_t, + char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA_CTX*); +void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); +char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const cm_sha2_uint8_t*, size_t, + char[SHA512_DIGEST_STRING_LENGTH]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHA2_H__ */ diff --git a/Source/cm_sha2_mangle.h b/Source/cm_sha2_mangle.h new file mode 100644 index 0000000..e73d131 --- /dev/null +++ b/Source/cm_sha2_mangle.h @@ -0,0 +1,51 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 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 cm_sha2_mangle_h +#define cm_sha2_mangle_h + +/* Mangle sha2 symbol names to avoid possible conflict with + implementations in other libraries to which CMake links. */ +#define SHA1_Data cmSHA1_Data +#define SHA1_End cmSHA1_End +#define SHA1_Final cmSHA1_Final +#define SHA1_Init cmSHA1_Init +#define SHA1_Internal_Transform cmSHA1_Internal_Transform +#define SHA1_Update cmSHA1_Update +#define SHA224_Data cmSHA224_Data +#define SHA224_End cmSHA224_End +#define SHA224_Final cmSHA224_Final +#define SHA224_Init cmSHA224_Init +#define SHA224_Internal_Transform cmSHA224_Internal_Transform +#define SHA224_Update cmSHA224_Update +#define SHA256_Data cmSHA256_Data +#define SHA256_End cmSHA256_End +#define SHA256_Final cmSHA256_Final +#define SHA256_Init cmSHA256_Init +#define SHA256_Internal_Init cmSHA256_Internal_Init +#define SHA256_Internal_Last cmSHA256_Internal_Last +#define SHA256_Internal_Transform cmSHA256_Internal_Transform +#define SHA256_Update cmSHA256_Update +#define SHA384_Data cmSHA384_Data +#define SHA384_End cmSHA384_End +#define SHA384_Final cmSHA384_Final +#define SHA384_Init cmSHA384_Init +#define SHA384_Update cmSHA384_Update +#define SHA512_Data cmSHA512_Data +#define SHA512_End cmSHA512_End +#define SHA512_Final cmSHA512_Final +#define SHA512_Init cmSHA512_Init +#define SHA512_Internal_Init cmSHA512_Internal_Init +#define SHA512_Internal_Last cmSHA512_Internal_Last +#define SHA512_Internal_Transform cmSHA512_Internal_Transform +#define SHA512_Update cmSHA512_Update + +#endif diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 1bf19c0..4d83293 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -128,7 +128,7 @@ public: #include <io.h> #include <direct.h> #define _unlink unlink -#endif +#endif /* The maximum length of a file name. */ #if defined(PATH_MAX) @@ -168,9 +168,9 @@ static inline char *realpath(const char *path, char *resolved_path) snprintf(resolved_path, maxlen, "%s", path); BPath normalized(resolved_path, NULL, true); const char *resolved = normalized.Path(); - if (resolved != NULL) // NULL == No such file. + if (resolved != NULL) // NULL == No such file. { - if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) + if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) { return resolved_path; } @@ -179,7 +179,7 @@ static inline char *realpath(const char *path, char *resolved_path) } #endif -#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) +#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) inline int Mkdir(const char* dir) { return _mkdir(dir); @@ -300,7 +300,7 @@ double SystemTools::GetTime(void) #endif } -class SystemToolsTranslationMap : +class SystemToolsTranslationMap : public kwsys_stl::map<kwsys_stl::string,kwsys_stl::string> { }; @@ -326,7 +326,7 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char kwsys_stl::string pathEnv = cpathEnv; // A hack to make the below algorithm work. - if(pathEnv[pathEnv.length()-1] != ':') + if(!pathEnv.empty() && pathEnv[pathEnv.length()-1] != pathSep[0]) { pathEnv += pathSep; } @@ -371,7 +371,7 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result) } } -#ifdef INTEL_COMPILER +#ifdef __INTEL_COMPILER #pragma warning disable 444 #endif @@ -392,7 +392,7 @@ kwsysDeletingCharVector::~kwsysDeletingCharVector() #endif } bool SystemTools::PutEnv(const char* value) -{ +{ static kwsysDeletingCharVector localEnvironment; char* envVar = new char[strlen(value)+1]; strcpy(envVar, value); @@ -403,18 +403,13 @@ bool SystemTools::PutEnv(const char* value) return ret == 0; } -#ifdef INTEL_COMPILER -#pragma warning restore 444 -#endif - - const char* SystemTools::GetExecutableExtension() { #if defined(_WIN32) || defined(__CYGWIN__) || defined(__VMS) return ".exe"; #else return ""; -#endif +#endif } @@ -482,7 +477,7 @@ void SystemTools::ReplaceString(kwsys_stl::string& source, { const char *src = source.c_str(); char *searchPos = const_cast<char *>(strstr(src,replace)); - + // get out quick if string is not found if (!searchPos) { @@ -499,7 +494,7 @@ void SystemTools::ReplaceString(kwsys_stl::string& source, char *orig = strdup(src); char *currentPos = orig; searchPos = searchPos - src + orig; - + // initialize the result source.erase(source.begin(),source.end()); do @@ -551,7 +546,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode, #endif // Read a registry value. -// Example : +// Example : // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath // => will return the data of the "default" value of the key // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root @@ -580,7 +575,7 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, second = primary.substr(start+1, valuenamepos-start-1); primary = primary.substr(0, start); - + HKEY primaryKey = HKEY_CURRENT_USER; if (primary == "HKEY_CURRENT_USER") { @@ -602,11 +597,11 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, { primaryKey = HKEY_USERS; } - + HKEY hKey; - if(RegOpenKeyEx(primaryKey, - second.c_str(), - 0, + if(RegOpenKeyEx(primaryKey, + second.c_str(), + 0, SystemToolsMakeRegistryMode(KEY_READ, view), &hKey) != ERROR_SUCCESS) { @@ -617,11 +612,11 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, DWORD dwType, dwSize; dwSize = 1023; char data[1024]; - if(RegQueryValueEx(hKey, - (LPTSTR)valuename.c_str(), - NULL, - &dwType, - (BYTE *)data, + if(RegQueryValueEx(hKey, + (LPTSTR)valuename.c_str(), + NULL, + &dwType, + (BYTE *)data, &dwSize) == ERROR_SUCCESS) { if (dwType == REG_SZ) @@ -656,7 +651,7 @@ bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &, // Write a registry value. -// Example : +// Example : // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath // => will set the data of the "default" value of the key // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root @@ -669,7 +664,7 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, kwsys_stl::string primary = key; kwsys_stl::string second; kwsys_stl::string valuename; - + size_t start = primary.find("\\"); if (start == kwsys_stl::string::npos) { @@ -684,7 +679,7 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, second = primary.substr(start+1, valuenamepos-start-1); primary = primary.substr(0, start); - + HKEY primaryKey = HKEY_CURRENT_USER; if (primary == "HKEY_CURRENT_USER") { @@ -706,13 +701,13 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, { primaryKey = HKEY_USERS; } - + HKEY hKey; DWORD dwDummy; char lpClass[] = ""; - if(RegCreateKeyEx(primaryKey, - second.c_str(), - 0, + if(RegCreateKeyEx(primaryKey, + second.c_str(), + 0, lpClass, REG_OPTION_NON_VOLATILE, SystemToolsMakeRegistryMode(KEY_WRITE, view), @@ -723,11 +718,11 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, return false; } - if(RegSetValueEx(hKey, - (LPTSTR)valuename.c_str(), - 0, - REG_SZ, - (CONST BYTE *)value, + if(RegSetValueEx(hKey, + (LPTSTR)valuename.c_str(), + 0, + REG_SZ, + (CONST BYTE *)value, (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS) { return true; @@ -742,7 +737,7 @@ bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64) #endif // Delete a registry value. -// Example : +// Example : // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath // => will delete the data of the "default" value of the key // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root @@ -754,7 +749,7 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) kwsys_stl::string primary = key; kwsys_stl::string second; kwsys_stl::string valuename; - + size_t start = primary.find("\\"); if (start == kwsys_stl::string::npos) { @@ -769,7 +764,7 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) second = primary.substr(start+1, valuenamepos-start-1); primary = primary.substr(0, start); - + HKEY primaryKey = HKEY_CURRENT_USER; if (primary == "HKEY_CURRENT_USER") { @@ -791,11 +786,11 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) { primaryKey = HKEY_USERS; } - + HKEY hKey; - if(RegOpenKeyEx(primaryKey, - second.c_str(), - 0, + if(RegOpenKeyEx(primaryKey, + second.c_str(), + 0, SystemToolsMakeRegistryMode(KEY_WRITE, view), &hKey) != ERROR_SUCCESS) { @@ -803,7 +798,7 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) } else { - if(RegDeleteValue(hKey, + if(RegDeleteValue(hKey, (LPTSTR)valuename.c_str()) == ERROR_SUCCESS) { RegCloseKey(hKey); @@ -824,17 +819,17 @@ bool SystemTools::SameFile(const char* file1, const char* file2) #ifdef _WIN32 HANDLE hFile1, hFile2; - hFile1 = CreateFile( file1, - GENERIC_READ, + hFile1 = CreateFile( file1, + GENERIC_READ, FILE_SHARE_READ , NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL ); - hFile2 = CreateFile( file2, - GENERIC_READ, - FILE_SHARE_READ, + hFile2 = CreateFile( file2, + GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, @@ -868,10 +863,10 @@ bool SystemTools::SameFile(const char* file1, const char* file2) { // see if the files are the same file // check the device inode and size - if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 && + if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 && memcmp(&fileStat2.st_ino, &fileStat1.st_ino, sizeof(fileStat1.st_ino)) == 0 && - fileStat2.st_size == fileStat1.st_size - ) + fileStat2.st_size == fileStat1.st_size + ) { return true; } @@ -1068,11 +1063,11 @@ kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s) #if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG) // MS has an assert that will fail if s[i] < 0; setting // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && + if ((int)s[i] >= 0 && isalpha(s[i]) && (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) #else if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif +#endif { n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i])); } @@ -1089,11 +1084,11 @@ kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s) #if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG) // MS has an assert that will fail if s[i] < 0; setting // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && + if ((int)s[i] >= 0 && isalpha(s[i]) && (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) #else if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif +#endif { n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i])); } @@ -1171,7 +1166,7 @@ char* SystemTools::AppendStrings( return newstr; } -// Return a lower case string +// Return a lower case string kwsys_stl::string SystemTools::LowerCase(const kwsys_stl::string& s) { kwsys_stl::string n; @@ -1183,7 +1178,7 @@ kwsys_stl::string SystemTools::LowerCase(const kwsys_stl::string& s) return n; } -// Return a lower case string +// Return a lower case string kwsys_stl::string SystemTools::UpperCase(const kwsys_stl::string& s) { kwsys_stl::string n; @@ -1313,7 +1308,7 @@ const char* SystemTools::FindLastString(const char* str1, const char* str2) { return NULL; } - + size_t len1 = strlen(str1), len2 = strlen(str2); if (len1 >= len2) { @@ -1341,8 +1336,8 @@ char* SystemTools::DuplicateString(const char* str) return NULL; } -// Return a cropped string -kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s, +// Return a cropped string +kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s, size_t max_len) { if (!s.size() || max_len == 0 || max_len >= s.size()) @@ -1386,7 +1381,7 @@ kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char se if(isPath && path[0] == '/') { path.erase(path.begin()); - paths.push_back("/"); + paths.push_back("/"); } kwsys_stl::string::size_type pos1 = 0; kwsys_stl::string::size_type pos2 = path.find(sep, pos1+1); @@ -1395,9 +1390,9 @@ kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char se paths.push_back(path.substr(pos1, pos2-pos1)); pos1 = pos2+1; pos2 = path.find(sep, pos1+1); - } + } paths.push_back(path.substr(pos1, pos2-pos1)); - + return paths; } @@ -1411,11 +1406,11 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap) // Quick-hack attempt at estimating the length of the string. // Should never under-estimate. - + // Start with the length of the format string itself. size_t length = strlen(format); - + // Increase the length for every argument in the format. const char* cur = format; @@ -1447,7 +1442,7 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap) { // Assume the argument contributes no more than 64 characters. length += 64; - + // Eat the argument. static_cast<void>(va_arg(ap, double)); } break; @@ -1455,24 +1450,24 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap) { // Assume the argument contributes no more than 64 characters. length += 64; - + // Eat the argument. static_cast<void>(va_arg(ap, int)); } break; } } - + // Move past the characters just tested. ++cur; } } - + return static_cast<int>(length); } kwsys_stl::string SystemTools::EscapeChars( - const char *str, - const char *chars_to_escape, + const char *str, + const char *chars_to_escape, char escape_char) { kwsys_stl::string n; @@ -1529,7 +1524,7 @@ static void ConvertVMSToUnix(kwsys_stl::string& path) } #endif -// convert windows slashes to unix slashes +// convert windows slashes to unix slashes void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path) { const char* pathCString = path.c_str(); @@ -1596,7 +1591,7 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path) } } #endif - // remove trailing slash if the path is more than + // remove trailing slash if the path is more than // a single / pathCString = path.c_str(); if(path.size() > 1 && *(pathCString+(path.size()-1)) == '/') @@ -1614,7 +1609,7 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path) kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path) { kwsys_stl::string ret = path; - + // remove // except at the beginning might be a cygwin drive kwsys_stl::string::size_type pos=1; while((pos = ret.find("//", pos)) != kwsys_stl::string::npos) @@ -1652,7 +1647,7 @@ kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path) // remove double slashes not at the start kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path) -{ +{ kwsys_stl::string ret; // make it big enough for all of path and double quotes ret.reserve(strlen(path)+3); @@ -1738,13 +1733,13 @@ bool SystemTools::FilesDiffer(const char* source, const char* destination) { struct stat statSource; - if (stat(source, &statSource) != 0) + if (stat(source, &statSource) != 0) { return true; } struct stat statDestination; - if (stat(destination, &statDestination) != 0) + if (stat(destination, &statDestination) != 0) { return true; } @@ -1790,7 +1785,7 @@ bool SystemTools::FilesDiffer(const char* source, { return true; } - + // If this block differs the file differs. if(memcmp(static_cast<const void*>(source_buf), static_cast<const void*>(dest_buf), @@ -1849,7 +1844,7 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination) // Open files #if defined(_WIN32) || defined(__CYGWIN__) - kwsys_ios::ifstream fin(source, + kwsys_ios::ifstream fin(source, kwsys_ios::ios::binary | kwsys_ios::ios::in); #else kwsys_ios::ifstream fin(source); @@ -1858,7 +1853,7 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination) { return false; } - + // try and remove the destination file so that read only destination files // can be written to. // If the remove fails continue so that files in read only directories @@ -1866,17 +1861,17 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination) SystemTools::RemoveFile(destination); #if defined(_WIN32) || defined(__CYGWIN__) - kwsys_ios::ofstream fout(destination, + kwsys_ios::ofstream fout(destination, kwsys_ios::ios::binary | kwsys_ios::ios::out | kwsys_ios::ios::trunc); #else - kwsys_ios::ofstream fout(destination, + kwsys_ios::ofstream fout(destination, kwsys_ios::ios::out | kwsys_ios::ios::trunc); #endif if(!fout) { return false; } - + // This copy loop is very sensitive on certain platforms with // slightly broken stream libraries (like HPUX). Normally, it is // incorrect to not check the error condition on the fin.read() @@ -1890,12 +1885,12 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination) fout.write(buffer, fin.gcount()); } } - + // Make sure the operating system has finished writing the file // before closing it. This will ensure the file is finished before // the check below. fout.flush(); - + fin.close(); fout.close(); @@ -1979,7 +1974,7 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination, unsigned long SystemTools::FileLength(const char* filename) { struct stat fs; - if (stat(filename, &fs) != 0) + if (stat(filename, &fs) != 0) { return 0; } @@ -2225,7 +2220,7 @@ kwsys_stl::string SystemTools { // Add the system search path to our path first kwsys_stl::vector<kwsys_stl::string> path; - if (!no_system_path) + if (!no_system_path) { SystemTools::GetPath(path, "CMAKE_FILE_PATH"); SystemTools::GetPath(path); @@ -2340,7 +2335,7 @@ kwsys_stl::string SystemTools::FindProgram( // first try with extensions if the os supports them if(extensions.size()) { - for(kwsys_stl::vector<kwsys_stl::string>::iterator i = + for(kwsys_stl::vector<kwsys_stl::string>::iterator i = extensions.begin(); i != extensions.end(); ++i) { tryPath = name; @@ -2368,7 +2363,7 @@ kwsys_stl::string SystemTools::FindProgram( } // now add the additional paths { - for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = + for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin(); i != userPaths.end(); ++i) { path.push_back(*i); @@ -2397,7 +2392,7 @@ kwsys_stl::string SystemTools::FindProgram( // first try with extensions if(extensions.size()) { - for(kwsys_stl::vector<kwsys_stl::string>::iterator ext + for(kwsys_stl::vector<kwsys_stl::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext) { tryPath = *p; @@ -2962,7 +2957,7 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot } // split up both paths into arrays of strings using / as a separator - kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(local, '/', true); + kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(local, '/', true); kwsys_stl::vector<kwsys::String> remoteSplit = SystemTools::SplitString(remote, '/', true); kwsys_stl::vector<kwsys::String> commonPath; // store shared parts of path in this array kwsys_stl::vector<kwsys::String> finalPath; // store the final relative path here @@ -3019,7 +3014,7 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot } } kwsys_stl::string relativePath; // result string - // now turn the array of directories into a unix path by puttint / + // now turn the array of directories into a unix path by puttint / // between each entry that does not already have one for(kwsys_stl::vector<String>::iterator vit1 = finalPath.begin(); vit1 != finalPath.end(); ++vit1) @@ -3396,7 +3391,7 @@ kwsys_stl::string SystemTools::GetFilenamePath(const kwsys_stl::string& filename { kwsys_stl::string fn = filename; SystemTools::ConvertToUnixSlashes(fn); - + kwsys_stl::string::size_type slash_pos = fn.rfind("/"); if(slash_pos != kwsys_stl::string::npos) { @@ -3515,7 +3510,7 @@ SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::string& filename) } bool SystemTools::FileHasSignature(const char *filename, - const char *signature, + const char *signature, long offset) { if (!filename || !signature) @@ -3547,9 +3542,9 @@ bool SystemTools::FileHasSignature(const char *filename, return res; } -SystemTools::FileTypeEnum +SystemTools::FileTypeEnum SystemTools::DetectFileType(const char *filename, - unsigned long length, + unsigned long length, double percent_bin) { if (!filename || percent_bin < 0) @@ -3577,13 +3572,13 @@ SystemTools::DetectFileType(const char *filename, // Loop over contents and count size_t text_count = 0; - + const unsigned char *ptr = buffer; const unsigned char *buffer_end = buffer + read_length; while (ptr != buffer_end) { - if ((*ptr >= 0x20 && *ptr <= 0x7F) || + if ((*ptr >= 0x20 && *ptr <= 0x7F) || *ptr == '\n' || *ptr == '\r' || *ptr == '\t') @@ -3595,7 +3590,7 @@ SystemTools::DetectFileType(const char *filename, delete [] buffer; - double current_percent_bin = + double current_percent_bin = (static_cast<double>(read_length - text_count) / static_cast<double>(read_length)); @@ -3607,8 +3602,8 @@ SystemTools::DetectFileType(const char *filename, return SystemTools::FileTypeText; } -bool SystemTools::LocateFileInDir(const char *filename, - const char *dir, +bool SystemTools::LocateFileInDir(const char *filename, + const char *dir, kwsys_stl::string& filename_found, int try_filename_dirs) { @@ -3621,7 +3616,7 @@ bool SystemTools::LocateFileInDir(const char *filename, kwsys_stl::string filename_base = SystemTools::GetFilenameName(filename); - // Check if 'dir' is really a directory + // Check if 'dir' is really a directory // If win32 and matches something like C:, accept it as a dir kwsys_stl::string real_dir; @@ -3645,7 +3640,7 @@ bool SystemTools::LocateFileInDir(const char *filename, if (filename_base.size() && dir) { size_t dir_len = strlen(dir); - int need_slash = + int need_slash = (dir_len && dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\'); kwsys_stl::string temp = dir; @@ -3676,7 +3671,7 @@ bool SystemTools::LocateFileInDir(const char *filename, filename_dir = SystemTools::GetFilenamePath(filename_dir); filename_dir_base = SystemTools::GetFilenameName(filename_dir); #if defined( _WIN32 ) - if (!filename_dir_base.size() || + if (!filename_dir_base.size() || filename_dir_base[filename_dir_base.size() - 1] == ':') #else if (!filename_dir_base.size()) @@ -3700,7 +3695,7 @@ bool SystemTools::LocateFileInDir(const char *filename, } while (!res && filename_dir_base.size()); } } - + return res; } @@ -3746,12 +3741,12 @@ bool SystemTools::FileIsFullPath(const char* in_name) bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath) { -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(WIN32) && !defined(__CYGWIN__) const int size = int(strlen(path)) +1; // size of return char *buffer = new char[size]; // create a buffer char *tempPath = new char[size]; // create a buffer int ret; - + // if the path passed in has quotes around it, first remove the quotes if (path[0] == '"' && path[strlen(path)-1] == '"') { @@ -3762,7 +3757,7 @@ bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath) { strcpy(tempPath,path); } - + buffer[0] = 0; ret = GetShortPathName(tempPath, buffer, size); @@ -3785,7 +3780,7 @@ bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath) #endif } -void SystemTools::SplitProgramFromArgs(const char* path, +void SystemTools::SplitProgramFromArgs(const char* path, kwsys_stl::string& program, kwsys_stl::string& args) { // see if this is a full path to a program @@ -3797,7 +3792,7 @@ void SystemTools::SplitProgramFromArgs(const char* path, return; } // Try to find the program in the path, note the program - // may have spaces in its name so we have to look for it + // may have spaces in its name so we have to look for it kwsys_stl::vector<kwsys_stl::string> e; kwsys_stl::string findProg = SystemTools::FindProgram(path, e); if(findProg.size()) @@ -3828,7 +3823,7 @@ void SystemTools::SplitProgramFromArgs(const char* path, args = dir.substr(spacePos, dir.size()-spacePos); return; } - // Now try and find the the program in the path + // Now try and find the the program in the path findProg = SystemTools::FindProgram(tryProg.c_str(), e); if(findProg.size()) { @@ -4203,23 +4198,23 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() if (!bOsVersionInfoEx) { osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { return 0; } } - + switch (osvi.dwPlatformId) { // Test for the Windows NT product family. case VER_PLATFORM_WIN32_NT: - + // Test for the specific product family. if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) { -#if (_MSC_VER >= 1300) +#if (_MSC_VER >= 1300) if (osvi.wProductType == VER_NT_WORKSTATION) { res += "Microsoft Windows Vista"; @@ -4259,7 +4254,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() { // Test for the workstation type. -#if (_MSC_VER >= 1300) +#if (_MSC_VER >= 1300) if (osvi.wProductType == VER_NT_WORKSTATION) { if (osvi.dwMajorVersion == 4) @@ -4278,7 +4273,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() } } } - + // Test for the server type. else if (osvi.wProductType == VER_NT_SERVER) @@ -4302,7 +4297,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() res += " Standard Edition"; } } - + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { if (osvi.wSuiteMask & VER_SUITE_DATACENTER) @@ -4319,7 +4314,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() } } - else if (osvi.dwMajorVersion <= 4) // Windows NT 4.0 + else if (osvi.dwMajorVersion <= 4) // Windows NT 4.0 { if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { @@ -4336,7 +4331,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() // Test for specific product on Windows NT 4.0 SP5 and earlier - else + else { HKEY hKey; #define BUFSIZE 80 @@ -4386,7 +4381,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() // Display service pack (if any) and build number. - if (osvi.dwMajorVersion == 4 && + if (osvi.dwMajorVersion == 4 && lstrcmpi(osvi.szCSDVersion, "Service Pack 6") == 0) { HKEY hKey; @@ -4415,7 +4410,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() res += buffer; res += ")"; } - + RegCloseKey(hKey); } else // Windows NT 3.51 and earlier or Windows 2000 and later @@ -4455,11 +4450,11 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { res += "Microsoft Windows Millennium Edition"; - } + } break; case VER_PLATFORM_WIN32s: - + res += "Microsoft Win32s"; break; } @@ -4469,7 +4464,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() } // ---------------------------------------------------------------------- -bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL, +bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL, kwsys_stl::string& protocol, kwsys_stl::string& dataglom ) { @@ -4487,12 +4482,12 @@ bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL, } // ---------------------------------------------------------------------- -bool SystemTools::ParseURL( const kwsys_stl::string& URL, +bool SystemTools::ParseURL( const kwsys_stl::string& URL, kwsys_stl::string& protocol, - kwsys_stl::string& username, - kwsys_stl::string& password, - kwsys_stl::string& hostname, - kwsys_stl::string& dataport, + kwsys_stl::string& username, + kwsys_stl::string& password, + kwsys_stl::string& hostname, + kwsys_stl::string& dataport, kwsys_stl::string& database ) { kwsys::RegularExpression urlRe( VTK_URL_REGEX ); @@ -4515,7 +4510,7 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL, hostname = urlRe.match( 6 ); dataport = urlRe.match( 8 ); database = urlRe.match( 9 ); - + return true; } diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 82fa8cd..b03f656 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -15,7 +15,7 @@ SET(KWSYS_DATE_STAMP_YEAR 2011) # KWSys version date month component. Format is MM. -SET(KWSYS_DATE_STAMP_MONTH 11) +SET(KWSYS_DATE_STAMP_MONTH 12) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 10) +SET(KWSYS_DATE_STAMP_DAY 16) |