diff options
82 files changed, 1390 insertions, 733 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 2576cde..754f14b 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -473,6 +473,12 @@ Available commands are: directory and it must exist. ``copy_if_different`` does follow symlinks. +``create_symlink <old> <new>`` + Create a symbolic link ``<new>`` naming ``<old>``. + + .. note:: + Path to where ``<new>`` symbolic link will be created has to exist beforehand. + ``echo [<string>...]`` Displays arguments as text. @@ -485,6 +491,9 @@ Available commands are: ``environment`` Display the current environment variables. +``false`` + Do nothing, with an exit code of 1. + ``make_directory <dir>...`` Create ``<dir>`` directories. If necessary, create parent directories too. If a directory already exists it will be @@ -602,18 +611,9 @@ Available commands are: Touch a file if it exists but do not create it. If a file does not exist it will be silently ignored. -``create_symlink <old> <new>`` - Create a symbolic link ``<new>`` naming ``<old>``. - -.. note:: - Path to where ``<new>`` symbolic link will be created has to exist beforehand. - ``true`` Do nothing, with an exit code of 0. -``false`` - Do nothing, with an exit code of 1. - Windows-specific Command-Line Tools ----------------------------------- diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst index 77e1ea9..f4a33e2 100644 --- a/Help/variable/MSVC_TOOLSET_VERSION.rst +++ b/Help/variable/MSVC_TOOLSET_VERSION.rst @@ -14,6 +14,7 @@ Known toolset version numbers are:: 120 = VS 2013 (12.0) 140 = VS 2015 (14.0) 141 = VS 2017 (15.0) + 142 = VS 2019 (16.0) Compiler versions newer than those known to CMake will be reported as the latest known toolset version. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c7648f1..8ed7b2f 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -226,8 +226,6 @@ set(SRCS cmExportTryCompileFileGenerator.cxx cmExportSet.h cmExportSet.cxx - cmExportSetMap.h - cmExportSetMap.cxx cmExternalMakefileProjectGenerator.cxx cmExternalMakefileProjectGenerator.h cmExtraCodeBlocksGenerator.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index c09c1ce..9a4f63e 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190919) +set(CMake_VERSION_PATCH 20190920) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index ce2c0ae..ab4371a 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmComputeLinkDepends.h" -#include "cmAlgorithms.h" #include "cmComputeComponentGraph.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -201,10 +200,7 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target, this->CCG = nullptr; } -cmComputeLinkDepends::~cmComputeLinkDepends() -{ - cmDeleteAll(this->InferredDependSets); -} +cmComputeLinkDepends::~cmComputeLinkDepends() = default; void cmComputeLinkDepends::SetOldLinkDirMode(bool b) { @@ -285,7 +281,7 @@ std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( item, static_cast<int>(this->EntryList.size())); auto lei = this->LinkEntryIndex.insert(index_entry).first; this->EntryList.emplace_back(); - this->InferredDependSets.push_back(nullptr); + this->InferredDependSets.emplace_back(); this->EntryConstraintGraph.emplace_back(); return lei; } @@ -325,7 +321,7 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) this->BFSQueue.push(qe); } else if (!entry.IsFlag) { // The item dependencies are not known. We need to infer them. - this->InferredDependSets[index] = new DependSetList; + this->InferredDependSets[index].Initialized = true; } } @@ -538,7 +534,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, } // If this item needs to have dependencies inferred, do so. - if (this->InferredDependSets[dependee_index]) { + if (this->InferredDependSets[dependee_index].Initialized) { // Make sure an entry exists to hold the set for the item. dependSets[dependee_index]; } @@ -546,7 +542,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, // Store the inferred dependency sets discovered for this list. for (auto const& dependSet : dependSets) { - this->InferredDependSets[dependSet.first]->push_back(dependSet.second); + this->InferredDependSets[dependSet.first].push_back(dependSet.second); } } @@ -573,14 +569,14 @@ void cmComputeLinkDepends::InferDependencies() depender_index < this->InferredDependSets.size(); ++depender_index) { // Skip items for which dependencies do not need to be inferred or // for which the inferred dependency sets are empty. - DependSetList* sets = this->InferredDependSets[depender_index]; - if (!sets || sets->empty()) { + DependSetList& sets = this->InferredDependSets[depender_index]; + if (!sets.Initialized || sets.empty()) { continue; } // Intersect the sets for this item. - DependSet common = sets->front(); - for (DependSet const& i : cmMakeRange(*sets).advance(1)) { + DependSet common = sets.front(); + for (DependSet const& i : cmMakeRange(sets).advance(1)) { DependSet intersection; std::set_intersection(common.begin(), common.end(), i.begin(), i.end(), std::inserter(intersection, intersection.begin())); diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index f0ac771..203cc68 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -106,8 +106,9 @@ private: }; struct DependSetList : public std::vector<DependSet> { + bool Initialized = false; }; - std::vector<DependSetList*> InferredDependSets; + std::vector<DependSetList> InferredDependSets; void InferDependencies(); // Ordering constraint graph adjacency list. diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 09dbbb1..832f38e 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -6,6 +6,7 @@ #include "cmComputeLinkDepends.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -406,6 +407,18 @@ cmComputeLinkInformation::~cmComputeLinkInformation() delete this->OrderDependentRPath; } +void cmComputeLinkInformation::AppendValues( + std::string& result, std::vector<BT<std::string>>& values) +{ + for (BT<std::string>& p : values) { + if (result.empty()) { + result.append(" "); + } + + result.append(p.Value); + } +} + cmComputeLinkInformation::ItemVector const& cmComputeLinkInformation::GetItems() const { @@ -418,6 +431,28 @@ std::vector<std::string> const& cmComputeLinkInformation::GetDirectories() return this->OrderLinkerSearchPath->GetOrderedDirectories(); } +std::vector<BT<std::string>> +cmComputeLinkInformation::GetDirectoriesWithBacktraces() +{ + std::vector<BT<std::string>> directoriesWithBacktraces; + + std::vector<BT<std::string>> targetLinkDirectores = + this->Target->GetLinkDirectories(this->Config, this->LinkLanguage); + + const std::vector<std::string>& orderedDirectories = this->GetDirectories(); + for (const std::string& dir : orderedDirectories) { + auto result = + std::find(targetLinkDirectores.begin(), targetLinkDirectores.end(), dir); + if (result != targetLinkDirectores.end()) { + directoriesWithBacktraces.emplace_back(std::move(*result)); + } else { + directoriesWithBacktraces.emplace_back(dir); + } + } + + return directoriesWithBacktraces; +} + std::string cmComputeLinkInformation::GetRPathLinkString() const { // If there is no separate linker runtime search flag (-rpath-link) diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 0f71381..d3345d9 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -17,6 +17,8 @@ class cmGlobalGenerator; class cmMakefile; class cmOrderDirectories; class cmake; +template <typename T> +class BT; /** \class cmComputeLinkInformation * \brief Compute link information for a target in one configuration. @@ -43,8 +45,10 @@ public: cmGeneratorTarget const* Target = nullptr; }; using ItemVector = std::vector<Item>; + void AppendValues(std::string& result, std::vector<BT<std::string>>& values); ItemVector const& GetItems() const; std::vector<std::string> const& GetDirectories() const; + std::vector<BT<std::string>> GetDirectoriesWithBacktraces(); std::vector<std::string> const& GetDepends() const; std::vector<std::string> const& GetFrameworkPaths() const; std::string GetLinkLanguage() const { return this->LinkLanguage; } @@ -66,6 +70,8 @@ public: std::string GetConfig() const { return this->Config; } + const cmGeneratorTarget* GetTarget() { return this->Target; } + private: void AddItem(std::string const& item, const cmGeneratorTarget* tgt); void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt); diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 2c0cbfd..ddb855b 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -17,6 +17,26 @@ #include <memory> #include <utility> +namespace { +void AppendPaths(const std::vector<std::string>& inputs, + cmGeneratorExpression& ge, cmLocalGenerator* lg, + std::string const& config, std::vector<std::string>& output) +{ + for (std::string const& in : inputs) { + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(in); + std::vector<std::string> result = + cmExpandedList(cge->Evaluate(lg, config)); + for (std::string& it : result) { + cmSystemTools::ConvertToUnixSlashes(it); + if (cmSystemTools::FileIsFullPath(it)) { + it = cmSystemTools::CollapseFullPath(it); + } + } + cmAppend(output, result); + } +} +} + cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg) @@ -46,25 +66,16 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, // lists on an empty command may have left this empty. // FIXME: Should we define behavior for removing empty commands? if (argv.empty()) { - argv.push_back(std::string()); + argv.emplace_back(); } this->CommandLines.push_back(std::move(argv)); } - std::vector<std::string> depends = this->CC.GetDepends(); - for (std::string const& d : depends) { - std::unique_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(d); - std::vector<std::string> result = - cmExpandedList(cge->Evaluate(this->LG, this->Config)); - for (std::string& it : result) { - cmSystemTools::ConvertToUnixSlashes(it); - if (cmSystemTools::FileIsFullPath(it)) { - it = cmSystemTools::CollapseFullPath(it); - } - } - cmAppend(this->Depends, result); - } + AppendPaths(cc.GetByproducts(), *this->GE, this->LG, this->Config, + this->Byproducts); + AppendPaths(cc.GetDepends(), *this->GE, this->LG, this->Config, + this->Depends); const std::string& workingdirectory = this->CC.GetWorkingDirectory(); if (!workingdirectory.empty()) { @@ -239,7 +250,7 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const { - return this->CC.GetByproducts(); + return this->Byproducts; } std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 766f4b8..d614302 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -23,6 +23,7 @@ class cmCustomCommandGenerator cmGeneratorExpression* GE; cmCustomCommandLines CommandLines; std::vector<std::vector<std::string>> EmulatorsWithArguments; + std::vector<std::string> Byproducts; std::vector<std::string> Depends; std::string WorkingDirectory; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index e9d2412..c751966 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -17,6 +17,7 @@ #include "cmake.h" #include <map> +#include <memory> #include <set> #include <sstream> #include <utility> @@ -283,7 +284,8 @@ void cmExportBuildFileGenerator::GetTargets( std::vector<std::string>& targets) const { if (this->ExportSet) { - for (cmTargetExport* te : *this->ExportSet->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->ExportSet->GetTargetExports()) { targets.push_back(te->TargetName); } return; diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 4046f91..2713856 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -13,7 +13,7 @@ #include "cmArgumentParser.h" #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportBuildFileGenerator.h" -#include "cmExportSetMap.h" +#include "cmExportSet.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -23,7 +23,6 @@ #include "cmSystemTools.h" #include "cmTarget.h" -class cmExportSet; class cmExecutionStatus; #if defined(__HAIKU__) @@ -121,7 +120,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); - cmExportSet* ExportSet = nullptr; + cmExportSet* exportSet = nullptr; if (args[0] == "EXPORT") { cmExportSetMap& setMap = gg->GetExportSets(); auto const it = setMap.find(arguments.ExportSetName); @@ -131,7 +130,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, this->SetError(e.str()); return false; } - ExportSet = it->second; + exportSet = &it->second; } else if (!arguments.Targets.empty() || cmContains(keywordsMissingValue, "TARGETS")) { for (std::string const& currentTarget : arguments.Targets) { @@ -180,8 +179,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, ebfg->SetExportFile(fname.c_str()); ebfg->SetNamespace(arguments.Namespace); ebfg->SetAppendMode(arguments.Append); - if (ExportSet != nullptr) { - ebfg->SetExportSet(ExportSet); + if (exportSet != nullptr) { + ebfg->SetExportSet(exportSet); } else { ebfg->SetTargets(targets); } @@ -197,7 +196,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, for (std::string const& ct : configurationTypes) { ebfg->AddConfiguration(ct); } - if (ExportSet != nullptr) { + if (exportSet != nullptr) { gg->AddBuildExportExportSet(ebfg); } else { gg->AddBuildExportSet(ebfg); diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx index 207ea41..2d732c1 100644 --- a/Source/cmExportInstallAndroidMKGenerator.cxx +++ b/Source/cmExportInstallAndroidMKGenerator.cxx @@ -3,6 +3,7 @@ #include "cmExportInstallAndroidMKGenerator.h" #include <cstddef> +#include <memory> #include <ostream> #include "cmExportBuildAndroidMKGenerator.h" @@ -35,7 +36,8 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode( } os << "_IMPORT_PREFIX := " << "$(LOCAL_PATH)" << path << "\n\n"; - for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { // Collect import properties for this target. if (te->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 4e3db09..0009b3a 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -3,7 +3,6 @@ #include "cmExportInstallFileGenerator.h" #include "cmExportSet.h" -#include "cmExportSetMap.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" @@ -19,6 +18,7 @@ #include "cmTarget.h" #include "cmTargetExport.h" +#include <memory> #include <sstream> #include <utility> @@ -40,12 +40,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { std::string expectedTargets; std::string sep; - for (cmTargetExport* te : - *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { expectedTargets += sep + this->Namespace + te->Target->GetExportName(); sep = " "; if (this->ExportedTargets.insert(te->Target).second) { - allTargets.push_back(te); + allTargets.push_back(te.get()); } else { std::ostringstream e; e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName() @@ -314,9 +314,11 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig( std::vector<std::string>& missingTargets) { // Add each target in the set to the export. - for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) { + for (std::unique_ptr<cmTargetExport> const& te : + this->IEGen->GetExportSet()->GetTargetExports()) { // Collect import properties for this target. - if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) { + if (this->GetExportTargetType(te.get()) == + cmStateEnums::INTERFACE_LIBRARY) { continue; } @@ -474,12 +476,10 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, const cmExportSetMap& exportSets = gg->GetExportSets(); for (auto const& expIt : exportSets) { - const cmExportSet* exportSet = expIt.second; - std::vector<cmTargetExport*> const* targets = - exportSet->GetTargetExports(); + const cmExportSet& exportSet = expIt.second; bool containsTarget = false; - for (cmTargetExport* target : *targets) { + for (auto const& target : exportSet.GetTargetExports()) { if (name == target->TargetName) { containsTarget = true; break; @@ -488,7 +488,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, if (containsTarget) { std::vector<cmInstallExportGenerator const*> const* installs = - exportSet->GetInstallations(); + exportSet.GetInstallations(); for (cmInstallExportGenerator const* install : *installs) { exportFiles.push_back(install->GetDestinationFile()); ns = install->GetNamespace(); diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index a6fa186..a20aa9a 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -2,28 +2,43 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportSet.h" -#include "cmAlgorithms.h" +#include <tuple> +#include <utility> + #include "cmLocalGenerator.h" #include "cmTargetExport.h" -cmExportSet::~cmExportSet() +cmExportSet::cmExportSet(std::string name) + : Name(std::move(name)) { - cmDeleteAll(this->TargetExports); } +cmExportSet::~cmExportSet() = default; + void cmExportSet::Compute(cmLocalGenerator* lg) { - for (cmTargetExport* tgtExport : this->TargetExports) { + for (std::unique_ptr<cmTargetExport>& tgtExport : this->TargetExports) { tgtExport->Target = lg->FindGeneratorTargetToUse(tgtExport->TargetName); } } -void cmExportSet::AddTargetExport(cmTargetExport* te) +void cmExportSet::AddTargetExport(std::unique_ptr<cmTargetExport> te) { - this->TargetExports.push_back(te); + this->TargetExports.emplace_back(std::move(te)); } void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation) { this->Installations.push_back(installation); } + +cmExportSet& cmExportSetMap::operator[](const std::string& name) +{ + auto it = this->find(name); + if (it == this->end()) // Export set not found + { + auto tup_name = std::make_tuple(name); + it = this->emplace(std::piecewise_construct, tup_name, tup_name).first; + } + return it->second; +} diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index d654c12..f0d921f 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h @@ -5,8 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> +#include <memory> #include <string> -#include <utility> #include <vector> class cmInstallExportGenerator; @@ -18,10 +19,7 @@ class cmExportSet { public: /// Construct an empty export set named \a name - cmExportSet(std::string name) - : Name(std::move(name)) - { - } + cmExportSet(std::string name); /// Destructor ~cmExportSet(); @@ -30,15 +28,15 @@ public: void Compute(cmLocalGenerator* lg); - void AddTargetExport(cmTargetExport* tgt); + void AddTargetExport(std::unique_ptr<cmTargetExport> tgt); void AddInstallation(cmInstallExportGenerator const* installation); std::string const& GetName() const { return this->Name; } - std::vector<cmTargetExport*> const* GetTargetExports() const + std::vector<std::unique_ptr<cmTargetExport>> const& GetTargetExports() const { - return &this->TargetExports; + return this->TargetExports; } std::vector<cmInstallExportGenerator const*> const* GetInstallations() const @@ -47,9 +45,21 @@ public: } private: - std::vector<cmTargetExport*> TargetExports; + std::vector<std::unique_ptr<cmTargetExport>> TargetExports; std::string Name; std::vector<cmInstallExportGenerator const*> Installations; }; +/// A name -> cmExportSet map with overloaded operator[]. +class cmExportSetMap : public std::map<std::string, cmExportSet> +{ +public: + /** \brief Overloaded operator[]. + * + * The operator is overloaded because cmExportSet has no default constructor: + * we do not want unnamed export sets. + */ + cmExportSet& operator[](const std::string& name); +}; + #endif diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx deleted file mode 100644 index 5c3f84f..0000000 --- a/Source/cmExportSetMap.cxx +++ /dev/null @@ -1,31 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmExportSetMap.h" - -#include "cmAlgorithms.h" -#include "cmExportSet.h" - -#include <utility> - -cmExportSet* cmExportSetMap::operator[](const std::string& name) -{ - auto it = this->find(name); - if (it == this->end()) // Export set not found - { - it = this->insert(std::make_pair(name, new cmExportSet(name))).first; - } - return it->second; -} - -void cmExportSetMap::clear() -{ - cmDeleteAll(*this); - this->derived::clear(); -} - -cmExportSetMap::cmExportSetMap() = default; - -cmExportSetMap::~cmExportSetMap() -{ - this->clear(); -} diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h deleted file mode 100644 index 0ef07ef..0000000 --- a/Source/cmExportSetMap.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmExportSetMap_h -#define cmExportSetMap_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <map> -#include <string> - -class cmExportSet; - -/// A name -> cmExportSet map with overloaded operator[]. -class cmExportSetMap : public std::map<std::string, cmExportSet*> -{ - using derived = std::map<std::string, cmExportSet*>; - -public: - /** \brief Overloaded operator[]. - * - * The operator is overloaded because cmExportSet has no default constructor: - * we do not want unnamed export sets. - */ - cmExportSet* operator[](const std::string& name); - - void clear(); - - cmExportSetMap(); - - /// Overloaded destructor deletes all member export sets. - ~cmExportSetMap(); - - cmExportSetMap(const cmExportSetMap&) = delete; - cmExportSetMap& operator=(const cmExportSetMap&) = delete; -}; - -#endif diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index e33ba2d..96ea071 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -1269,8 +1269,8 @@ Json::Value Target::DumpLinkCommandFragments() std::string linkLanguageFlags; std::vector<BT<std::string>> linkFlags; std::string frameworkPath; - std::string linkPath; - std::string linkLibs; + std::vector<BT<std::string>> linkPath; + std::vector<BT<std::string>> linkLibs; cmLocalGenerator* lg = this->GT->GetLocalGenerator(); cmLinkLineComputer linkLineComputer(lg, lg->GetStateSnapshot().GetDirectory()); @@ -1279,8 +1279,6 @@ Json::Value Target::DumpLinkCommandFragments() this->GT); linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags); frameworkPath = cmTrimWhitespace(frameworkPath); - linkPath = cmTrimWhitespace(linkPath); - linkLibs = cmTrimWhitespace(linkLibs); if (!linkLanguageFlags.empty()) { linkFragments.append( @@ -1301,13 +1299,19 @@ Json::Value Target::DumpLinkCommandFragments() } if (!linkPath.empty()) { - linkFragments.append( - this->DumpCommandFragment(std::move(linkPath), "libraryPath")); + for (BT<std::string> frag : linkPath) { + frag.Value = cmTrimWhitespace(frag.Value); + linkFragments.append( + this->DumpCommandFragment(this->ToJBT(frag), "libraryPath")); + } } if (!linkLibs.empty()) { - linkFragments.append( - this->DumpCommandFragment(std::move(linkLibs), "libraries")); + for (BT<std::string> frag : linkLibs) { + frag.Value = cmTrimWhitespace(frag.Value); + linkFragments.append( + this->DumpCommandFragment(this->ToJBT(frag), "libraries")); + } } return linkFragments; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 136996e..18ca478 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3746,7 +3746,7 @@ void processLinkDirectories(cmGeneratorTarget const* tgt, // in case projects set the LINK_DIRECTORIES property directly. cmSystemTools::ConvertToUnixSlashes(entryDirectory); if (uniqueDirectories.insert(entryDirectory).second) { - directories.emplace_back(entryDirectory); + directories.emplace_back(entryDirectory, entry.Backtrace); if (debugDirectories) { usedDirectories += " * " + entryDirectory + "\n"; } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index d67c725..372e658 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -17,7 +17,7 @@ #include "cmAlgorithms.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" -#include "cmExportSetMap.h" +#include "cmExportSet.h" #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index e7bb1ac..f7050d4 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -11,7 +11,6 @@ #include "cmArgumentParser.h" #include "cmExportSet.h" -#include "cmExportSetMap.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallCommandArguments.h" @@ -736,7 +735,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Add this install rule to an export if one was specified and // this is not a namelink-only rule. if (!exports.empty() && !namelinkOnly) { - cmTargetExport* te = new cmTargetExport; + auto te = cm::make_unique<cmTargetExport>(); te->TargetName = target.GetName(); te->ArchiveGenerator = archiveGenerator; te->BundleGenerator = bundleGenerator; @@ -745,12 +744,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) te->LibraryGenerator = libraryGenerator; te->RuntimeGenerator = runtimeGenerator; te->ObjectsGenerator = objectGenerator; - this->Makefile->GetGlobalGenerator() - ->GetExportSets()[exports] - ->AddTargetExport(te); - te->InterfaceIncludeDirectories = cmJoin(includesArgs.GetIncludeDirs(), ";"); + + this->Makefile->GetGlobalGenerator() + ->GetExportSets()[exports] + .AddTargetExport(std::move(te)); } } @@ -1273,7 +1272,7 @@ bool cmInstallCommand::HandleExportAndroidMKMode( fname = "Android.mk"; } - cmExportSet* exportSet = + cmExportSet& exportSet = this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; cmInstallGenerator::MessageLevel message = @@ -1281,7 +1280,7 @@ bool cmInstallCommand::HandleExportAndroidMKMode( // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), + &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, true); @@ -1367,10 +1366,10 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) } } - cmExportSet* exportSet = + cmExportSet& exportSet = this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; if (exportOld) { - for (cmTargetExport* te : *exportSet->GetTargetExports()) { + for (auto const& te : exportSet.GetTargetExports()) { cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName); const bool newCMP0022Behavior = @@ -1392,7 +1391,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), + &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, false); diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 0b3617b..cba68be 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -123,7 +123,7 @@ size_t cmInstallExportGenerator::GetMaxConfigLength() const void cmInstallExportGenerator::GenerateScript(std::ostream& os) { // Skip empty sets. - if (ExportSet->GetTargetExports()->empty()) { + if (ExportSet->GetTargetExports().empty()) { std::ostringstream e; e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() << "\""; diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 91c551f..0dc6236 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -4,10 +4,13 @@ #include "cmLinkLineComputer.h" #include <sstream> +#include <utility> #include <vector> #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" +#include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmOutputConverter.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" @@ -56,6 +59,15 @@ std::string cmLinkLineComputer::ConvertToLinkReference( std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) { std::string linkLibs; + std::vector<BT<std::string>> linkLibsList; + this->ComputeLinkLibs(cli, linkLibsList); + cli.AppendValues(linkLibs, linkLibsList); + return linkLibs; +} + +void cmLinkLineComputer::ComputeLinkLibs( + cmComputeLinkInformation& cli, std::vector<BT<std::string>>& linkLibraries) +{ using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); for (auto const& item : items) { @@ -63,16 +75,33 @@ std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; } + + BT<std::string> linkLib; if (item.IsPath) { - linkLibs += cli.GetLibLinkFileFlag(); - linkLibs += + linkLib.Value += cli.GetLibLinkFileFlag(); + linkLib.Value += this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value)); } else { - linkLibs += item.Value; + linkLib.Value += item.Value; } - linkLibs += " "; + linkLib.Value += " "; + + const cmLinkImplementation* linkImpl = + cli.GetTarget()->GetLinkImplementation(cli.GetConfig()); + + for (const cmLinkImplItem& iter : linkImpl->Libraries) { + if (iter.Target != nullptr && + iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + std::string libPath = iter.Target->GetLocation(cli.GetConfig()); + if (item.Value == libPath) { + linkLib.Backtrace = iter.Backtrace; + break; + } + } + } + + linkLibraries.emplace_back(linkLib); } - return linkLibs; } std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input) @@ -101,8 +130,19 @@ std::string cmLinkLineComputer::ComputeLinkPath( std::string const& libPathTerminator) { std::string linkPath; + std::vector<BT<std::string>> linkPathList; + this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList); + cli.AppendValues(linkPath, linkPathList); + return linkPath; +} +void cmLinkLineComputer::ComputeLinkPath( + cmComputeLinkInformation& cli, std::string const& libPathFlag, + std::string const& libPathTerminator, std::vector<BT<std::string>>& linkPath) +{ if (cli.GetLinkLanguage() == "Swift") { + std::string linkPathNoBT; + for (const cmComputeLinkInformation::Item& item : cli.GetItems()) { const cmGeneratorTarget* target = item.Target; if (!target) { @@ -116,20 +156,23 @@ std::string cmLinkLineComputer::ComputeLinkPath( type = cmStateEnums::ImportLibraryArtifact; } - linkPath += cmStrCat(" ", libPathFlag, - item.Target->GetDirectory(cli.GetConfig(), type), - libPathTerminator, " "); + linkPathNoBT += cmStrCat( + " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type), + libPathTerminator, " "); } } - } - for (std::string const& libDir : cli.GetDirectories()) { - linkPath += - cmStrCat(" ", libPathFlag, this->ConvertToOutputForExisting(libDir), - libPathTerminator, " "); + if (!linkPathNoBT.empty()) { + linkPath.emplace_back(std::move(linkPathNoBT)); + } } - return linkPath; + for (BT<std::string> libDir : cli.GetDirectoriesWithBacktraces()) { + libDir.Value = cmStrCat(" ", libPathFlag, + this->ConvertToOutputForExisting(libDir.Value), + libPathTerminator, " "); + linkPath.emplace_back(libDir); + } } std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli) @@ -179,13 +222,30 @@ std::string cmLinkLineComputer::ComputeFrameworkPath( std::string cmLinkLineComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { - std::ostringstream fout; - fout << this->ComputeRPath(cli); + std::string linkLibraries; + std::vector<BT<std::string>> linkLibrariesList; + this->ComputeLinkLibraries(cli, stdLibString, linkLibrariesList); + cli.AppendValues(linkLibraries, linkLibrariesList); + return linkLibraries; +} + +void cmLinkLineComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) +{ + std::ostringstream rpathOut; + rpathOut << this->ComputeRPath(cli); + + std::string rpath = rpathOut.str(); + if (!rpath.empty()) { + linkLibraries.emplace_back(std::move(rpath)); + } // Write the library flags to the build rule. - fout << this->ComputeLinkLibs(cli); + this->ComputeLinkLibs(cli, linkLibraries); // Add the linker runtime search path if any. + std::ostringstream fout; std::string rpath_link = cli.GetRPathLinkString(); if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) { fout << cli.GetRPathLinkFlag(); @@ -198,7 +258,10 @@ std::string cmLinkLineComputer::ComputeLinkLibraries( fout << stdLibString << " "; } - return fout.str(); + std::string remainingLibs = fout.str(); + if (!remainingLibs.empty()) { + linkLibraries.emplace_back(remainingLibs); + } } std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target, diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h index 2355c32..f426976 100644 --- a/Source/cmLinkLineComputer.h +++ b/Source/cmLinkLineComputer.h @@ -7,12 +7,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmStateDirectory.h" class cmComputeLinkInformation; class cmGeneratorTarget; class cmOutputConverter; +template <typename T> +class BT; class cmLinkLineComputer { @@ -34,17 +37,28 @@ public: std::string const& libPathFlag, std::string const& libPathTerminator); + void ComputeLinkPath(cmComputeLinkInformation& cli, + std::string const& libPathFlag, + std::string const& libPathTerminator, + std::vector<BT<std::string>>& linkPath); + std::string ComputeFrameworkPath(cmComputeLinkInformation& cli, std::string const& fwSearchFlag); - virtual std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, - std::string const& stdLibString); + std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, + std::string const& stdLibString); + + virtual void ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries); virtual std::string GetLinkerLanguage(cmGeneratorTarget* target, std::string const& config); protected: std::string ComputeLinkLibs(cmComputeLinkInformation& cli); + void ComputeLinkLibs(cmComputeLinkInformation& cli, + std::vector<BT<std::string>>& linkLibraries); std::string ComputeRPath(cmComputeLinkInformation& cli); std::string ConvertToOutputFormat(std::string const& input); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 1a602ca..d845652 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -4,13 +4,14 @@ #include "cmLinkLineDeviceComputer.h" #include <set> -#include <sstream> #include <utility> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateDirectory.h" @@ -67,12 +68,10 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( return false; } -std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( - cmComputeLinkInformation& cli, std::string const& stdLibString) +void cmLinkLineDeviceComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) { - // Write the library flags to the build rule. - std::ostringstream fout; - // Generate the unique set of link items when device linking. // The nvcc device linker is designed so that each static library // with device symbols only needs to be listed once as it doesn't @@ -110,7 +109,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } } - std::string out; + BT<std::string> linkLib; if (item.IsPath) { // nvcc understands absolute paths to libraries ending in '.a' or '.lib'. // These should be passed to nvlink. Other extensions need to be left @@ -118,7 +117,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( // can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'. if (cmHasLiteralSuffix(item.Value, ".a") || cmHasLiteralSuffix(item.Value, ".lib")) { - out += this->ConvertToOutputFormat( + linkLib.Value += this->ConvertToOutputFormat( this->ConvertToLinkReference(item.Value)); } } else if (item.Value == "-framework") { @@ -127,19 +126,33 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( skipItemAfterFramework = true; continue; } else if (cmLinkItemValidForDevice(item.Value)) { - out += item.Value; + linkLib.Value += item.Value; } - if (emitted.insert(out).second) { - fout << out << " "; + if (emitted.insert(linkLib.Value).second) { + linkLib.Value += " "; + + const cmLinkImplementation* linkImpl = + cli.GetTarget()->GetLinkImplementation(cli.GetConfig()); + + for (const cmLinkImplItem& iter : linkImpl->Libraries) { + if (iter.Target != nullptr && + iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + std::string libPath = iter.Target->GetLocation(cli.GetConfig()); + if (item.Value == libPath) { + linkLib.Backtrace = iter.Backtrace; + break; + } + } + } + + linkLibraries.emplace_back(linkLib); } } if (!stdLibString.empty()) { - fout << stdLibString << " "; + linkLibraries.emplace_back(cmStrCat(stdLibString, ' ')); } - - return fout.str(); } std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h index 0ea5f69..a9b01cd 100644 --- a/Source/cmLinkLineDeviceComputer.h +++ b/Source/cmLinkLineDeviceComputer.h @@ -7,6 +7,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmLinkLineComputer.h" @@ -15,6 +16,8 @@ class cmGeneratorTarget; class cmLocalGenerator; class cmOutputConverter; class cmStateDirectory; +template <typename T> +class BT; class cmLinkLineDeviceComputer : public cmLinkLineComputer { @@ -29,8 +32,9 @@ public: bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli); - std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, - std::string const& stdLibString) override; + void ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) override; std::string GetLinkerLanguage(cmGeneratorTarget* target, std::string const& config) override; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 840f55f..e059548 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1200,17 +1200,21 @@ void cmLocalGenerator::GetTargetFlags( std::string& linkLibs, std::string& flags, std::string& linkFlags, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target) { - std::vector<BT<std::string>> tmpLinkFlags; - this->GetTargetFlags(linkLineComputer, config, linkLibs, flags, tmpLinkFlags, - frameworkPath, linkPath, target); - this->AppendFlags(linkFlags, tmpLinkFlags); + std::vector<BT<std::string>> linkFlagsList; + std::vector<BT<std::string>> linkPathList; + std::vector<BT<std::string>> linkLibsList; + this->GetTargetFlags(linkLineComputer, config, linkLibsList, flags, + linkFlagsList, frameworkPath, linkPathList, target); + this->AppendFlags(linkFlags, linkFlagsList); + this->AppendFlags(linkPath, linkPathList); + this->AppendFlags(linkLibs, linkLibsList); } void cmLocalGenerator::GetTargetFlags( cmLinkLineComputer* linkLineComputer, const std::string& config, - std::string& linkLibs, std::string& flags, + std::vector<BT<std::string>>& linkLibs, std::string& flags, std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath, - std::string& linkPath, cmGeneratorTarget* target) + std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target) { const std::string buildType = cmSystemTools::UpperCase(config); cmComputeLinkInformation* pcli = target->GetLinkInformation(config); @@ -1528,6 +1532,19 @@ void cmLocalGenerator::OutputLinkLibraries( std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath) { + std::vector<BT<std::string>> linkLibrariesList; + std::vector<BT<std::string>> linkPathList; + this->OutputLinkLibraries(pcli, linkLineComputer, linkLibrariesList, + frameworkPath, linkPathList); + pcli->AppendValues(linkLibraries, linkLibrariesList); + pcli->AppendValues(linkPath, linkPathList); +} + +void cmLocalGenerator::OutputLinkLibraries( + cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer, + std::vector<BT<std::string>>& linkLibraries, std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath) +{ cmComputeLinkInformation& cli = *pcli; std::string linkLanguage = cli.GetLinkLanguage(); @@ -1559,10 +1576,9 @@ void cmLocalGenerator::OutputLinkLibraries( cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG")); frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag); - linkPath = - linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator); - - linkLibraries = linkLineComputer->ComputeLinkLibraries(cli, stdLibString); + linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator, + linkPath); + linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries); } std::string cmLocalGenerator::GetLinkLibsCMP0065( @@ -2376,6 +2392,14 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str()); } + // Add pchHeader to source files, which will + // be grouped as "Precompile Header File" + auto pchHeader_sf = this->Makefile->GetOrCreateSource( + pchHeader, false, cmSourceFileLocationKind::Known); + std::string err; + pchHeader_sf->ResolveFullPath(&err); + target->AddSource(pchHeader); + for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) { cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader); cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile); @@ -2400,7 +2424,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, } if (!this->GetGlobalGenerator()->IsXcode()) { - sf->SetProperty("OBJECT_DEPENDS", pchFile.c_str()); + sf->AppendProperty("OBJECT_DEPENDS", pchFile.c_str()); + sf->AppendProperty("OBJECT_DEPENDS", pchHeader.c_str()); sf->SetProperty("COMPILE_OPTIONS", useOptionList.c_str()); } } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 34f58bd..512df26 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -382,12 +382,11 @@ public: std::string& flags, std::string& linkFlags, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target); - void GetTargetFlags(cmLinkLineComputer* linkLineComputer, - const std::string& config, std::string& linkLibs, - std::string& flags, - std::vector<BT<std::string>>& linkFlags, - std::string& frameworkPath, std::string& linkPath, - cmGeneratorTarget* target); + void GetTargetFlags( + cmLinkLineComputer* linkLineComputer, const std::string& config, + std::vector<BT<std::string>>& linkLibs, std::string& flags, + std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target); void GetTargetDefines(cmGeneratorTarget const* target, std::string const& config, std::string const& lang, std::set<std::string>& defines) const; @@ -430,6 +429,11 @@ protected: cmLinkLineComputer* linkLineComputer, std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath); + void OutputLinkLibraries(cmComputeLinkInformation* pcli, + cmLinkLineComputer* linkLineComputer, + std::vector<BT<std::string>>& linkLibraries, + std::string& frameworkPath, + std::vector<BT<std::string>>& linkPath); // Handle old-style install rules stored in the targets. void GenerateTargetInstallRules( diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 6c1dfc9..a7be04e 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -161,8 +161,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles( continue; } std::vector<cmSourceFile const*> objectSources; - gt->GetObjectSources( - objectSources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); + gt->GetObjectSources(objectSources, this->ConfigName); // Compute full path to object file directory for this target. std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->GetTargetDirectory(gt), '/'); @@ -1864,9 +1863,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( << "_TARGET_INCLUDE_PATH\n"; std::vector<std::string> includes; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->GetIncludeDirectories(includes, target, implicitLang.first, config); + this->GetIncludeDirectories(includes, target, implicitLang.first, + this->ConfigName); std::string binaryDir = this->GetState()->GetBinaryDirectory(); if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) { std::string const& sourceDir = this->GetState()->GetSourceDirectory(); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index c67c367..34081ed 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -103,6 +103,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->AddSourceGroup("", "^.*$"); this->AddSourceGroup("Source Files", CM_SOURCE_REGEX); this->AddSourceGroup("Header Files", CM_HEADER_REGEX); + this->AddSourceGroup("Precompile Header File", CM_PCH_REGEX); this->AddSourceGroup("CMake Rules", "\\.rule$"); this->AddSourceGroup("Resources", CM_RESOURCE_REGEX); this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); @@ -820,7 +821,23 @@ void cmMakefile::ConfigureFinalPass() } } -void cmMakefile::AddCustomCommandToTarget( +bool cmMakefile::ValidateCustomCommand( + const cmCustomCommandLines& commandLines) const +{ + // TODO: More strict? + for (cmCustomCommandLine const& cl : commandLines) { + if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') { + std::ostringstream e; + e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; + this->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; + } + } + + return true; +} + +cmTarget* cmMakefile::AddCustomCommandToTarget( const std::string& target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, @@ -863,31 +880,51 @@ void cmMakefile::AddCustomCommandToTarget( this->IssueMessage(messageType, e.str()); } - return; + return nullptr; } - cmTarget& t = ti->second; + cmTarget* t = &ti->second; if (objLibraryCommands == RejectObjectLibraryCommands && - t.GetType() == cmStateEnums::OBJECT_LIBRARY) { + t->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::ostringstream e; e << "Target \"" << target << "\" is an OBJECT library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return; + return nullptr; } - if (t.GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) { std::ostringstream e; e << "Target \"" << target << "\" is an INTERFACE library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return; + return nullptr; + } + + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines)) { + return t; } // Always create the byproduct sources and mark them generated. this->CreateGeneratedSources(byproducts); + this->CommitCustomCommandToTarget( + t, byproducts, depends, commandLines, type, comment, workingDir, + escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists); + + return t; +} + +void cmMakefile::CommitCustomCommandToTarget( + cmTarget* target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle, + bool uses_terminal, const std::string& depfile, const std::string& job_pool, + bool command_expand_lists) +{ // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; cmCustomCommand cc(this, no_output, byproducts, depends, commandLines, @@ -900,16 +937,16 @@ void cmMakefile::AddCustomCommandToTarget( cc.SetJobPool(job_pool); switch (type) { case cmTarget::PRE_BUILD: - t.AddPreBuildCommand(cc); + target->AddPreBuildCommand(cc); break; case cmTarget::PRE_LINK: - t.AddPreLinkCommand(cc); + target->AddPreLinkCommand(cc); break; case cmTarget::POST_BUILD: - t.AddPostBuildCommand(cc); + target->AddPostBuildCommand(cc); break; } - this->UpdateOutputToSourceMap(byproducts, &t); + this->UpdateOutputToSourceMap(byproducts, target); } void cmMakefile::UpdateOutputToSourceMap( @@ -943,6 +980,23 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct, } cmSourceFile* cmMakefile::AddCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const std::string& main_dependency, const cmCustomCommandLines& commandLines, + const char* comment, const char* workingDir, bool replace, + bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, + const std::string& depfile, const std::string& job_pool) +{ + std::vector<std::string> outputs; + outputs.push_back(output); + std::vector<std::string> no_byproducts; + cmImplicitDependsList no_implicit_depends; + return this->AddCustomCommandToOutput( + outputs, no_byproducts, depends, main_dependency, no_implicit_depends, + commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, + command_expand_lists, depfile, job_pool); +} + +cmSourceFile* cmMakefile::AddCustomCommandToOutput( const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const std::string& main_dependency, @@ -958,20 +1012,31 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( return nullptr; } - // Validate custom commands. TODO: More strict? - for (cmCustomCommandLine const& cl : commandLines) { - if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') { - std::ostringstream e; - e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; - this->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return nullptr; - } + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines)) { + return nullptr; } // Always create the output sources and mark them generated. - this->CreateGeneratedSources(outputs, cmSourceFileLocationKind::Known); - this->CreateGeneratedSources(byproducts, cmSourceFileLocationKind::Known); + this->CreateGeneratedSources(outputs); + this->CreateGeneratedSources(byproducts); + return this->CommitCustomCommandToOutput( + outputs, byproducts, depends, main_dependency, implicit_depends, + commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, + command_expand_lists, depfile, job_pool); +} + +cmSourceFile* cmMakefile::CommitCustomCommandToOutput( + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines, const char* comment, + const char* workingDir, bool replace, bool escapeOldStyle, + bool uses_terminal, bool command_expand_lists, const std::string& depfile, + const std::string& job_pool) +{ // Choose a source file on which to store the custom command. cmSourceFile* file = nullptr; if (!commandLines.empty() && !main_dependency.empty()) { @@ -1080,23 +1145,6 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& output, } } -cmSourceFile* cmMakefile::AddCustomCommandToOutput( - const std::string& output, const std::vector<std::string>& depends, - const std::string& main_dependency, const cmCustomCommandLines& commandLines, - const char* comment, const char* workingDir, bool replace, - bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, - const std::string& depfile, const std::string& job_pool) -{ - std::vector<std::string> outputs; - outputs.push_back(output); - std::vector<std::string> no_byproducts; - cmImplicitDependsList no_implicit_depends; - return this->AddCustomCommandToOutput( - outputs, no_byproducts, depends, main_dependency, no_implicit_depends, - commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); -} - void cmMakefile::AddCustomCommandOldStyle( const std::string& target, const std::vector<std::string>& outputs, const std::vector<std::string>& depends, const std::string& source, @@ -1115,41 +1163,50 @@ void cmMakefile::AddCustomCommandOldStyle( return; } - // Each output must get its own copy of this rule. - cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|" - "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" - "hm|hpp|hxx|in|txx|inl)$"); - for (std::string const& oi : outputs) { - // Get the name of this output. - const char* output = oi.c_str(); - cmSourceFile* sf; - - // Choose whether to use a main dependency. - if (sourceFiles.find(source)) { - // The source looks like a real file. Use it as the main dependency. - sf = this->AddCustomCommandToOutput(output, depends, source, - commandLines, comment, nullptr); - } else { - // The source may not be a real file. Do not use a main dependency. - std::string no_main_dependency; - std::vector<std::string> depends2 = depends; - depends2.push_back(source); - sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency, - commandLines, comment, nullptr); - } + auto ti = this->Targets.find(target); + cmTarget* t = ti != this->Targets.end() ? &ti->second : nullptr; + auto addRuleFileToTarget = [=](cmSourceFile* sf) { // If the rule was added to the source (and not a .rule file), // then add the source to the target to make sure the rule is // included. - if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) { - auto ti = this->Targets.find(target); - if (ti != this->Targets.end()) { - ti->second.AddSource(sf->ResolveFullPath()); + if (!sf->GetPropertyAsBool("__CMAKE_RULE")) { + if (t) { + t->AddSource(sf->ResolveFullPath()); } else { cmSystemTools::Error("Attempt to add a custom rule to a target " "that does not exist yet for target " + target); - return; + } + } + }; + + // Each output must get its own copy of this rule. + cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|" + "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" + "hm|hpp|hxx|in|txx|inl)$"); + + // Choose whether to use a main dependency. + if (sourceFiles.find(source)) { + // The source looks like a real file. Use it as the main dependency. + for (std::string const& output : outputs) { + cmSourceFile* sf = this->AddCustomCommandToOutput( + output, depends, source, commandLines, comment, nullptr); + if (sf) { + addRuleFileToTarget(sf); + } + } + } else { + std::string no_main_dependency; + std::vector<std::string> depends2 = depends; + depends2.push_back(source); + + // The source may not be a real file. Do not use a main dependency. + for (std::string const& output : outputs) { + cmSourceFile* sf = this->AddCustomCommandToOutput( + output, depends2, no_main_dependency, commandLines, comment, nullptr); + if (sf) { + addRuleFileToTarget(sf); } } } @@ -1160,16 +1217,34 @@ bool cmMakefile::AppendCustomCommandToOutput( const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines) { + // Check as good as we can if there will be a command for this output. + if (!this->MightHaveCustomCommand(output)) { + return false; + } + + // Validate custom commands. + if (this->ValidateCustomCommand(commandLines)) { + // Add command factory to allow generator expressions in output. + this->CommitAppendCustomCommandToOutput(output, depends, implicit_depends, + commandLines); + } + + return true; +} + +void cmMakefile::CommitAppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines) +{ // Lookup an existing command. if (cmSourceFile* sf = this->GetSourceFileWithOutput(output)) { if (cmCustomCommand* cc = sf->GetCustomCommand()) { cc->AppendCommands(commandLines); cc->AppendDepends(depends); cc->AppendImplicitDepends(implicit_depends); - return true; } } - return false; } cmTarget* cmMakefile::AddUtilityCommand( @@ -1201,41 +1276,71 @@ cmTarget* cmMakefile::AddUtilityCommand( target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - if (!comment) { - // Use an empty comment to avoid generation of default comment. - comment = ""; + // Validate custom commands. + if (!this->ValidateCustomCommand(commandLines) || + (commandLines.empty() && depends.empty())) { + return target; } - // Store the custom command in the target. - if (!commandLines.empty() || !depends.empty()) { - // Always create the byproduct sources and mark them generated. - this->CreateGeneratedSources(byproducts, cmSourceFileLocationKind::Known); - - std::string force = - cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); - std::vector<std::string> forced; - forced.push_back(force); - std::string no_main_dependency; - cmImplicitDependsList no_implicit_depends; - bool no_replace = false; - this->AddCustomCommandToOutput( - forced, byproducts, depends, no_main_dependency, no_implicit_depends, - commandLines, comment, workingDirectory, no_replace, escapeOldStyle, - uses_terminal, command_expand_lists, /*depfile=*/"", job_pool); - cmSourceFile* sf = target->AddSourceCMP0049(force); + // Always create the byproduct sources and mark them generated. + this->CreateGeneratedSources(byproducts); + std::string force = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); + this->CreateGeneratedSource(force); + std::string forceCMP0049 = target->GetSourceCMP0049(force); + { + cmSourceFile* sf = nullptr; + if (!forceCMP0049.empty()) { + sf = this->GetOrCreateSource(forceCMP0049, false, + cmSourceFileLocationKind::Known); + } // The output is not actually created so mark it symbolic. if (sf) { sf->SetProperty("SYMBOLIC", "1"); } else { cmSystemTools::Error("Could not get source file entry for " + force); } + } - this->UpdateOutputToSourceMap(byproducts, target); + if (!comment) { + // Use an empty comment to avoid generation of default comment. + comment = ""; } + + this->CommitUtilityCommand(target, force, forceCMP0049, workingDirectory, + byproducts, depends, commandLines, escapeOldStyle, + comment, uses_terminal, command_expand_lists, + job_pool); + return target; } +void cmMakefile::CommitUtilityCommand( + cmTarget* target, const std::string& force, const std::string& forceCMP0049, + const char* workingDirectory, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, bool escapeOldStyle, + const char* comment, bool uses_terminal, bool command_expand_lists, + const std::string& job_pool) +{ + std::vector<std::string> forced; + forced.push_back(force); + std::string no_main_dependency; + cmImplicitDependsList no_implicit_depends; + bool no_replace = false; + cmSourceFile* sf = this->AddCustomCommandToOutput( + forced, byproducts, depends, no_main_dependency, no_implicit_depends, + commandLines, comment, workingDirectory, no_replace, escapeOldStyle, + uses_terminal, command_expand_lists, /*depfile=*/"", job_pool); + if (!forceCMP0049.empty()) { + target->AddSource(forceCMP0049); + } + if (sf) { + this->UpdateOutputToSourceMap(byproducts, target); + } +} + static void s_AddDefineFlag(std::string const& flag, std::string& dflags) { // remove any \n\r @@ -2169,6 +2274,18 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput( return nullptr; } +bool cmMakefile::MightHaveCustomCommand(const std::string& name) const +{ + // This will have to be changed for delaying custom command creation, because + // GetSourceFileWithOutput requires the command to be already created. + if (cmSourceFile* sf = this->GetSourceFileWithOutput(name)) { + if (sf->GetCustomCommand()) { + return true; + } + } + return false; +} + #if !defined(CMAKE_BOOTSTRAP) cmSourceGroup* cmMakefile::GetSourceGroup( const std::vector<std::string>& name) const @@ -3413,13 +3530,19 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName, return this->CreateSource(sourceName, generated, kind); } +void cmMakefile::CreateGeneratedSource(const std::string& output) +{ + if (cmSourceFile* out = this->GetOrCreateSource( + output, true, cmSourceFileLocationKind::Known)) { + out->SetProperty("GENERATED", "1"); + } +} + void cmMakefile::CreateGeneratedSources( - const std::vector<std::string>& outputs, cmSourceFileLocationKind kind) + const std::vector<std::string>& outputs) { for (std::string const& output : outputs) { - if (cmSourceFile* out = this->GetOrCreateSource(output, true, kind)) { - out->SetProperty("GENERATED", "1"); - } + this->CreateGeneratedSource(output); } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index bf405a5..db37477 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -172,7 +172,7 @@ public: }; /** Add a custom command to the build. */ - void AddCustomCommandToTarget( + cmTarget* AddCustomCommandToTarget( const std::string& target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, @@ -181,18 +181,18 @@ public: const std::string& job_pool = "", bool command_expand_lists = false, ObjectLibraryCommands objLibraryCommands = RejectObjectLibraryCommands); cmSourceFile* AddCustomCommandToOutput( - const std::vector<std::string>& outputs, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, + const std::string& output, const std::vector<std::string>& depends, const std::string& main_dependency, - const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, const std::string& depfile = "", const std::string& job_pool = ""); cmSourceFile* AddCustomCommandToOutput( - const std::string& output, const std::vector<std::string>& depends, + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, @@ -1059,9 +1059,42 @@ private: bool atOnly, const char* filename, long line, bool replaceAt) const; - void CreateGeneratedSources( + bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const; + + void CommitCustomCommandToTarget( + cmTarget* target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle, + bool uses_terminal, const std::string& depfile, + const std::string& job_pool, bool command_expand_lists); + cmSourceFile* CommitCustomCommandToOutput( const std::vector<std::string>& outputs, - cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous); + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const std::string& main_dependency, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines, const char* comment, + const char* workingDir, bool replace, bool escapeOldStyle, + bool uses_terminal, bool command_expand_lists, const std::string& depfile, + const std::string& job_pool); + void CommitAppendCustomCommandToOutput( + const std::string& output, const std::vector<std::string>& depends, + const cmImplicitDependsList& implicit_depends, + const cmCustomCommandLines& commandLines); + + void CommitUtilityCommand(cmTarget* target, const std::string& force, + const std::string& forceCMP0049, + const char* workingDirectory, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, + bool escapeOldStyle, const char* comment, + bool uses_terminal, bool command_expand_lists, + const std::string& job_pool); + + void CreateGeneratedSource(const std::string& output); + void CreateGeneratedSources(const std::vector<std::string>& outputs); /** * See LinearGetSourceFileWithOutput for background information @@ -1096,6 +1129,11 @@ private: void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source, bool byproduct); + /** + * Return if the provided source file might have a custom command. + */ + bool MightHaveCustomCommand(const std::string& name) const; + bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature, std::string* error = nullptr) const; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 477badd..482af22 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -150,16 +150,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() { // -- Write the custom commands for this target - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - // Evaluates generator expressions and expands prop_value auto evaluatedFiles = - [this, &config](const char* prop_value) -> std::vector<std::string> { + [this](const char* prop_value) -> std::vector<std::string> { std::vector<std::string> files; cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); - cmExpandList(cge->Evaluate(this->LocalGenerator, config, false, + cmExpandList(cge->Evaluate(this->LocalGenerator, this->ConfigName, false, this->GeneratorTarget, nullptr, nullptr), files); return files; @@ -191,7 +188,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // First generate the object rule files. Save a list of all object // files for this target. std::vector<cmSourceFile const*> customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, config); + this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); std::string currentBinDir = this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmSourceFile const* sf : customCommands) { @@ -224,7 +221,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->GetPostBuildCommands()); for (const auto& be : buildEventCommands) { - const std::vector<std::string>& byproducts = be.GetByproducts(); + cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator); + const std::vector<std::string>& byproducts = beg.GetByproducts(); for (std::string const& byproduct : byproducts) { this->CleanFiles.insert( this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, @@ -233,17 +231,17 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } std::vector<cmSourceFile const*> headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, config); + this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( headerSources, this->MacOSXContentGenerator); std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, config); + this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( extraSources, this->MacOSXContentGenerator); const char* pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; - this->GeneratorTarget->GetExternalObjects(externalObjects, config); + this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName); for (cmSourceFile const* sf : externalObjects) { auto const& objectFileName = sf->GetFullPath(); if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { @@ -251,7 +249,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } std::vector<cmSourceFile const*> objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, config); + this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName); for (cmSourceFile const* sf : objectSources) { // Generate this object file's rule file. this->WriteObjectRuleFiles(*sf); @@ -1610,10 +1608,8 @@ void cmMakefileTargetGenerator::CreateLinkLibs( { std::string frameworkPath; std::string linkPath; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = - this->GeneratorTarget->GetLinkInformation(config); + this->GeneratorTarget->GetLinkInformation(this->ConfigName); this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, linkPath); linkLibs = frameworkPath + linkPath + linkLibs; @@ -1706,13 +1702,12 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, bool useResponseFile = this->Makefile->IsOn(responseVar); std::vector<std::string> includes; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, - lang, config); + lang, this->ConfigName); std::string includeFlags = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, lang, false, useResponseFile, config); + includes, this->GeneratorTarget, lang, false, useResponseFile, + this->ConfigName); if (includeFlags.empty()) { return; } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 8c88f6c..2ab5adf 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -777,11 +777,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() << cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) << " target " << this->GetTargetName() << "\n\n"; - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); { std::vector<cmSourceFile const*> customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, config); + this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); for (cmSourceFile const* sf : customCommands) { cmCustomCommand const* cc = sf->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget( @@ -793,13 +791,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() } { std::vector<cmSourceFile const*> headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, config); + this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( headerSources, this->MacOSXContentGenerator.get()); } { std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, config); + this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName); this->OSXBundleGenerator->GenerateMacOSXContentStatements( extraSources, this->MacOSXContentGenerator.get()); } @@ -808,7 +806,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; - this->GeneratorTarget->GetExternalObjects(externalObjects, config); + this->GeneratorTarget->GetExternalObjects(externalObjects, + this->ConfigName); for (cmSourceFile const* sf : externalObjects) { const auto objectFileName = this->GetSourceFilePath(sf); if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) { @@ -863,7 +862,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() { std::vector<cmSourceFile const*> objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, config); + this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName); for (cmSourceFile const* sf : objectSources) { this->WriteObjectBuildStatement(sf); } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index dd36d45..ff465c7 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -135,6 +135,8 @@ private: "hpj" \ "|bat)$" +#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$" + #define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$" #endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ca12c87..1b88db6 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -695,13 +695,9 @@ std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s) return src; } -cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s) +std::string cmTarget::GetSourceCMP0049(const std::string& s) { - std::string src = impl->ProcessSourceItemCMP0049(s); - if (!s.empty() && src.empty()) { - return nullptr; - } - return this->AddSource(src); + return impl->ProcessSourceItemCMP0049(s); } struct CreateLocation diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e9bcffe..f4726d3 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -103,7 +103,7 @@ public: //! Add sources to the target. void AddSources(std::vector<std::string> const& srcs); void AddTracedSources(std::vector<std::string> const& srcs); - cmSourceFile* AddSourceCMP0049(const std::string& src); + std::string GetSourceCMP0049(const std::string& src); cmSourceFile* AddSource(const std::string& src, bool before = false); //! how we identify a library, by name and type diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index dc9f01d..3fd1955 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -67,8 +67,8 @@ class CommandLineArgumentsInternal { public: CommandLineArgumentsInternal() - : UnknownArgumentCallback{ KWSYS_NULLPTR } - , ClientData{ KWSYS_NULLPTR } + : UnknownArgumentCallback{ nullptr } + , ClientData{ nullptr } , LastArgument{ 0 } { } @@ -187,7 +187,7 @@ int CommandLineArguments::Parse() switch (cs->ArgumentType) { case NO_ARGUMENT: // No value - if (!this->PopulateVariable(cs, KWSYS_NULLPTR)) { + if (!this->PopulateVariable(cs, nullptr)) { return 0; } break; @@ -340,7 +340,7 @@ void CommandLineArguments::AddCallback(const char* argument, s.Callback = callback; s.CallData = call_data; s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE; - s.Variable = KWSYS_NULLPTR; + s.Variable = nullptr; s.Help = help; this->Internals->Callbacks[argument] = s; @@ -355,8 +355,8 @@ void CommandLineArguments::AddArgument(const char* argument, CommandLineArgumentsCallbackStructure s; s.Argument = argument; s.ArgumentType = type; - s.Callback = KWSYS_NULLPTR; - s.CallData = KWSYS_NULLPTR; + s.Callback = nullptr; + s.CallData = nullptr; s.VariableType = vtype; s.Variable = variable; s.Help = help; @@ -427,7 +427,7 @@ const char* CommandLineArguments::GetHelp(const char* arg) CommandLineArguments::Internal::CallbacksMap::iterator it = this->Internals->Callbacks.find(arg); if (it == this->Internals->Callbacks.end()) { - return KWSYS_NULLPTR; + return nullptr; } // Since several arguments may point to the same argument, find the one this @@ -621,7 +621,7 @@ void CommandLineArguments::PopulateVariable(bool* variable, void CommandLineArguments::PopulateVariable(int* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; *variable = static_cast<int>(strtol(value.c_str(), &res, 10)); // if ( res && *res ) // { @@ -632,7 +632,7 @@ void CommandLineArguments::PopulateVariable(int* variable, void CommandLineArguments::PopulateVariable(double* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; *variable = strtod(value.c_str(), &res); // if ( res && *res ) // { @@ -669,7 +669,7 @@ void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, void CommandLineArguments::PopulateVariable(std::vector<int>* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10))); // if ( res && *res ) // { @@ -680,7 +680,7 @@ void CommandLineArguments::PopulateVariable(std::vector<int>* variable, void CommandLineArguments::PopulateVariable(std::vector<double>* variable, const std::string& value) { - char* res = KWSYS_NULLPTR; + char* res = nullptr; variable->push_back(strtod(value.c_str(), &res)); // if ( res && *res ) // { diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in index 92ffea3..29a2dd1 100644 --- a/Source/kwsys/Configure.hxx.in +++ b/Source/kwsys/Configure.hxx.in @@ -58,7 +58,6 @@ # define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \ @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H # define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH -# define KWSYS_NULLPTR @KWSYS_NAMESPACE@_NULLPTR # define KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP \ @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP #endif diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in index 73a1efb..49dbdf7 100644 --- a/Source/kwsys/ConsoleBuf.hxx.in +++ b/Source/kwsys/ConsoleBuf.hxx.in @@ -116,7 +116,7 @@ protected: DWORD charsWritten; success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(), - &charsWritten, NULL) == 0 + &charsWritten, nullptr) == 0 ? false : true; } else { @@ -124,8 +124,9 @@ protected: std::string buffer; success = encodeOutputBuffer(wbuffer, buffer); if (success) { - success = ::WriteFile(m_hOutput, buffer.c_str(), - (DWORD)buffer.size(), &bytesWritten, NULL) == 0 + success = + ::WriteFile(m_hOutput, buffer.c_str(), (DWORD)buffer.size(), + &bytesWritten, nullptr) == 0 ? false : true; } @@ -152,7 +153,7 @@ protected: DWORD charsRead; if (ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead, - NULL) == 0 || + nullptr) == 0 || charsRead == 0) { _setg(true); return Traits::eof(); @@ -168,7 +169,7 @@ protected: return Traits::eof(); } char* buffer = new char[size.LowPart]; - while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, NULL) == + while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) == 0) { if (GetLastError() == ERROR_MORE_DATA) { strbuffer += std::string(buffer, bytesRead); @@ -327,11 +328,12 @@ private: } const int length = WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), NULL, 0, NULL, NULL); + (int)wbuffer.size(), nullptr, 0, nullptr, nullptr); char* buf = new char[length]; const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), buf, length, NULL, NULL) > 0 + (int)wbuffer.size(), buf, length, nullptr, + nullptr) > 0 ? true : false; buffer = std::string(buf, length); @@ -356,7 +358,7 @@ private: length -= BOMsize; } const size_t wlength = static_cast<size_t>(MultiByteToWideChar( - actualCodepage, 0, data, static_cast<int>(length), NULL, 0)); + actualCodepage, 0, data, static_cast<int>(length), nullptr, 0)); wchar_t* wbuf = new wchar_t[wlength]; const bool success = MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length), diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 59530a4..e379182 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -48,7 +48,7 @@ unsigned long Directory::GetNumberOfFiles() const const char* Directory::GetFile(unsigned long dindex) const { if (dindex >= this->Internal->Files.size()) { - return KWSYS_NULLPTR; + return nullptr; } return this->Internal->Files[dindex].c_str(); } diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index b93a215..a4b8641 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -223,15 +223,15 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, NULL); + CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, nullptr); DWORD llFlags = 0; if (flags & SearchBesideLibrary) { llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH; } - return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), NULL, - llFlags); + return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), + nullptr, llFlags); } int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) @@ -289,9 +289,9 @@ const char* DynamicLoader::LastError() DWORD error = GetLastError(); DWORD length = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL); + lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, nullptr); static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1]; @@ -305,7 +305,7 @@ const char* DynamicLoader::LastError() } if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str, - DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) { + DYNLOAD_ERROR_BUFFER_SIZE, nullptr, nullptr)) { /* WideCharToMultiByte failed. Use a default message. */ _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, "DynamicLoader encountered error 0x%X. " @@ -372,7 +372,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::SymbolPointer psym; } result; - result.psym = NULL; + result.psym = nullptr; if (!lib) { last_dynamic_err = B_BAD_VALUE; @@ -384,7 +384,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid); if (rc != B_OK) { last_dynamic_err = rc; - result.psym = NULL; + result.psym = nullptr; } } return result.psym; @@ -412,7 +412,7 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, 0, NULL); + CHECK_OPEN_FLAGS(flags, 0, nullptr); char* name = (char*)calloc(1, libname.size() + 1); dld_init(program_invocation_name); @@ -458,7 +458,7 @@ namespace KWSYS_NAMESPACE { DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( const std::string& libname, int flags) { - CHECK_OPEN_FLAGS(flags, 0, NULL); + CHECK_OPEN_FLAGS(flags, 0, nullptr); return dlopen(libname.c_str(), RTLD_LAZY); } diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx index 251deef..4593c92 100644 --- a/Source/kwsys/EncodingCXX.cxx +++ b/Source/kwsys/EncodingCXX.cxx @@ -65,7 +65,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac, for (int i = 0; i < ac; i++) { this->argv_[i] = strdup(av[i]); } - this->argv_[ac] = KWSYS_NULLPTR; + this->argv_[ac] = nullptr; } Encoding::CommandLineArguments::CommandLineArguments(int ac, @@ -75,7 +75,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac, for (int i = 0; i < ac; i++) { this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]); } - this->argv_[ac] = KWSYS_NULLPTR; + this->argv_[ac] = nullptr; } Encoding::CommandLineArguments::~CommandLineArguments() @@ -90,7 +90,7 @@ Encoding::CommandLineArguments::CommandLineArguments( { this->argv_.resize(other.argv_.size()); for (size_t i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR; + this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; } } @@ -105,7 +105,7 @@ Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=( this->argv_.resize(other.argv_.size()); for (i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR; + this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; } } @@ -128,8 +128,9 @@ std::wstring Encoding::ToWide(const std::string& str) { std::wstring wstr; # if defined(_WIN32) - const int wlength = MultiByteToWideChar( - KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), int(str.size()), NULL, 0); + const int wlength = + MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), + int(str.size()), nullptr, 0); if (wlength > 0) { wchar_t* wdata = new wchar_t[wlength]; int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), @@ -162,12 +163,12 @@ std::string Encoding::ToNarrow(const std::wstring& str) # if defined(_WIN32) int length = WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), NULL, 0, NULL, NULL); + int(str.size()), nullptr, 0, nullptr, nullptr); if (length > 0) { char* data = new char[length]; int r = WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), data, length, NULL, NULL); + int(str.size()), data, length, nullptr, nullptr); if (r > 0) { nstr = std::string(data, length); } @@ -193,7 +194,7 @@ std::string Encoding::ToNarrow(const std::wstring& str) std::wstring Encoding::ToWide(const char* cstr) { std::wstring wstr; - size_t length = kwsysEncoding_mbstowcs(KWSYS_NULLPTR, cstr, 0) + 1; + size_t length = kwsysEncoding_mbstowcs(nullptr, cstr, 0) + 1; if (length > 0) { std::vector<wchar_t> wchars(length); if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) { @@ -206,7 +207,7 @@ std::wstring Encoding::ToWide(const char* cstr) std::string Encoding::ToNarrow(const wchar_t* wcstr) { std::string str; - size_t length = kwsysEncoding_wcstombs(KWSYS_NULLPTR, wcstr, 0) + 1; + size_t length = kwsysEncoding_wcstombs(nullptr, wcstr, 0) + 1; if (length > 0) { std::vector<char> chars(length); if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) { @@ -227,9 +228,9 @@ std::wstring Encoding::ToWindowsExtendedPath(std::string const& source) /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that * won't return a large enough buffer size if the input is too small */ - wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3; + wfull_len = GetFullPathNameW(wsource.c_str(), 0, nullptr, nullptr) + 3; std::vector<wchar_t> wfull(wfull_len); - GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL); + GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], nullptr); /* This should get the correct size without any extra padding from the * previous size workaround. */ diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 829c138..34bb0d0 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -431,7 +431,7 @@ void Glob::SetRelative(const char* dir) const char* Glob::GetRelative() { if (this->Relative.empty()) { - return KWSYS_NULLPTR; + return nullptr; } return this->Relative.c_str(); } diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in index 4c3bde1..170766f 100644 --- a/Source/kwsys/Glob.hxx.in +++ b/Source/kwsys/Glob.hxx.in @@ -54,7 +54,7 @@ public: ~Glob(); //! Find all files that match the pattern. - bool FindFiles(const std::string& inexpr, GlobMessages* messages = 0); + bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr); //! Return the list of files that matched. std::vector<std::string>& GetFiles(); diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx index 3e10765..5e6f8da 100644 --- a/Source/kwsys/RegularExpression.cxx +++ b/Source/kwsys/RegularExpression.cxx @@ -37,7 +37,7 @@ namespace KWSYS_NAMESPACE { RegularExpression::RegularExpression(const RegularExpression& rxp) { if (!rxp.program) { - this->program = KWSYS_NULLPTR; + this->program = nullptr; return; } int ind; @@ -48,7 +48,7 @@ RegularExpression::RegularExpression(const RegularExpression& rxp) // Copy pointers into last successful "find" operation this->regmatch = rxp.regmatch; this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != KWSYS_NULLPTR) { + if (rxp.regmust != nullptr) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -69,7 +69,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp) return *this; } if (!rxp.program) { - this->program = KWSYS_NULLPTR; + this->program = nullptr; return *this; } int ind; @@ -81,7 +81,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp) // Copy pointers into last successful "find" operation this->regmatch = rxp.regmatch; this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != KWSYS_NULLPTR) { + if (rxp.regmust != nullptr) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -164,8 +164,8 @@ bool RegularExpression::deep_equal(const RegularExpression& rxp) const * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string + * regmust string (pointer into program) that match must include, or + * nullptr regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection @@ -339,7 +339,7 @@ bool RegularExpression::compile(const char* exp) const char* longest; int flags; - if (exp == KWSYS_NULLPTR) { + if (exp == nullptr) { // RAISE Error, SYM(RegularExpression), SYM(No_Expr), printf("RegularExpression::compile(): No expression supplied.\n"); return false; @@ -367,13 +367,13 @@ bool RegularExpression::compile(const char* exp) // Allocate space. //#ifndef _WIN32 - if (this->program != KWSYS_NULLPTR) + if (this->program != nullptr) delete[] this->program; //#endif this->program = new char[comp.regsize]; this->progsize = static_cast<int>(comp.regsize); - if (this->program == KWSYS_NULLPTR) { + if (this->program == nullptr) { // RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory), printf("RegularExpression::compile(): Out of memory.\n"); return false; @@ -389,7 +389,7 @@ bool RegularExpression::compile(const char* exp) // Dig out information for optimizations. this->regstart = '\0'; // Worst-case defaults. this->reganch = 0; - this->regmust = KWSYS_NULLPTR; + this->regmust = nullptr; this->regmlen = 0; scan = this->program + 1; // First BRANCH. if (OP(regnext(scan)) == END) { // Only one top-level choice. @@ -410,9 +410,9 @@ bool RegularExpression::compile(const char* exp) // absence of others. // if (flags & SPSTART) { - longest = KWSYS_NULLPTR; + longest = nullptr; size_t len = 0; - for (; scan != KWSYS_NULLPTR; scan = regnext(scan)) + for (; scan != nullptr; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); @@ -448,19 +448,19 @@ char* RegExpCompile::reg(int paren, int* flagp) if (regnpar >= RegularExpressionMatch::NSUBEXP) { // RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens), printf("RegularExpression::compile(): Too many parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } parno = regnpar; regnpar++; ret = regnode(static_cast<char>(OPEN + parno)); } else - ret = KWSYS_NULLPTR; + ret = nullptr; // Pick up the branches, linking them together. br = regbranch(&flags); - if (br == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); - if (ret != KWSYS_NULLPTR) + if (br == nullptr) + return (nullptr); + if (ret != nullptr) regtail(ret, br); // OPEN -> first. else ret = br; @@ -470,8 +470,8 @@ char* RegExpCompile::reg(int paren, int* flagp) while (*regparse == '|') { regparse++; br = regbranch(&flags); - if (br == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (br == nullptr) + return (nullptr); regtail(ret, br); // BRANCH -> BRANCH. if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; @@ -483,23 +483,23 @@ char* RegExpCompile::reg(int paren, int* flagp) regtail(ret, ender); // Hook the tails of the branches to the closing node. - for (br = ret; br != KWSYS_NULLPTR; br = regnext(br)) + for (br = ret; br != nullptr; br = regnext(br)) regoptail(br, ender); // Check for proper termination. if (paren && *regparse++ != ')') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } else if (!paren && *regparse != '\0') { if (*regparse == ')') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return KWSYS_NULLPTR; + return nullptr; } else { // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); - return KWSYS_NULLPTR; + return nullptr; } // NOTREACHED } @@ -521,19 +521,19 @@ char* RegExpCompile::regbranch(int* flagp) *flagp = WORST; // Tentatively. ret = regnode(BRANCH); - chain = KWSYS_NULLPTR; + chain = nullptr; while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { latest = regpiece(&flags); - if (latest == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (latest == nullptr) + return (nullptr); *flagp |= flags & HASWIDTH; - if (chain == KWSYS_NULLPTR) // First piece. + if (chain == nullptr) // First piece. *flagp |= flags & SPSTART; else regtail(chain, latest); chain = latest; } - if (chain == KWSYS_NULLPTR) // Loop ran zero times. + if (chain == nullptr) // Loop ran zero times. regnode(NOTHING); return (ret); @@ -556,8 +556,8 @@ char* RegExpCompile::regpiece(int* flagp) int flags; ret = regatom(&flags); - if (ret == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (ret == nullptr) + return (nullptr); op = *regparse; if (!ISMULT(op)) { @@ -568,7 +568,7 @@ char* RegExpCompile::regpiece(int* flagp) if (!(flags & HASWIDTH) && op != '?') { // RAISE Error, SYM(RegularExpression), SYM(Empty_Operand), printf("RegularExpression::compile() : *+ operand could be empty.\n"); - return KWSYS_NULLPTR; + return nullptr; } *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH); @@ -602,7 +602,7 @@ char* RegExpCompile::regpiece(int* flagp) if (ISMULT(*regparse)) { // RAISE Error, SYM(RegularExpression), SYM(Nested_Operand), printf("RegularExpression::compile(): Nested *?+.\n"); - return KWSYS_NULLPTR; + return nullptr; } return (ret); } @@ -655,7 +655,7 @@ char* RegExpCompile::regatom(int* flagp) if (rxpclass > rxpclassend + 1) { // RAISE Error, SYM(RegularExpression), SYM(Invalid_Range), printf("RegularExpression::compile(): Invalid range in [].\n"); - return KWSYS_NULLPTR; + return nullptr; } for (; rxpclass <= rxpclassend; rxpclass++) regc(static_cast<char>(rxpclass)); @@ -668,15 +668,15 @@ char* RegExpCompile::regatom(int* flagp) if (*regparse != ']') { // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket), printf("RegularExpression::compile(): Unmatched [].\n"); - return KWSYS_NULLPTR; + return nullptr; } regparse++; *flagp |= HASWIDTH | SIMPLE; } break; case '(': ret = reg(1, &flags); - if (ret == KWSYS_NULLPTR) - return (KWSYS_NULLPTR); + if (ret == nullptr) + return (nullptr); *flagp |= flags & (HASWIDTH | SPSTART); break; case '\0': @@ -684,18 +684,18 @@ char* RegExpCompile::regatom(int* flagp) case ')': // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); // Never here - return KWSYS_NULLPTR; + return nullptr; case '?': case '+': case '*': // RAISE Error, SYM(RegularExpression), SYM(No_Operand), printf("RegularExpression::compile(): ?+* follows nothing.\n"); - return KWSYS_NULLPTR; + return nullptr; case '\\': if (*regparse == '\0') { // RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash), printf("RegularExpression::compile(): Trailing backslash.\n"); - return KWSYS_NULLPTR; + return nullptr; } ret = regnode(EXACTLY); regc(*regparse++); @@ -711,7 +711,7 @@ char* RegExpCompile::regatom(int* flagp) if (len <= 0) { // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), printf("RegularExpression::compile(): Internal error.\n"); - return KWSYS_NULLPTR; + return nullptr; } ender = *(regparse + len); if (len > 1 && ISMULT(ender)) @@ -809,7 +809,7 @@ void RegExpCompile::regtail(char* p, const char* val) scan = p; for (;;) { temp = regnext(scan); - if (temp == KWSYS_NULLPTR) + if (temp == nullptr) break; scan = temp; } @@ -828,7 +828,7 @@ void RegExpCompile::regtail(char* p, const char* val) void RegExpCompile::regoptail(char* p, const char* val) { // "Operandless" and "op != BRANCH" are synonymous in practice. - if (p == KWSYS_NULLPTR || p == regdummyptr || OP(p) != BRANCH) + if (p == nullptr || p == regdummyptr || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } @@ -878,14 +878,14 @@ bool RegularExpression::find(char const* string, } // If there is a "must appear" string, look for it. - if (this->regmust != KWSYS_NULLPTR) { + if (this->regmust != nullptr) { s = string; - while ((s = strchr(s, this->regmust[0])) != KWSYS_NULLPTR) { + while ((s = strchr(s, this->regmust[0])) != nullptr) { if (strncmp(s, this->regmust, this->regmlen) == 0) break; // Found it. s++; } - if (s == KWSYS_NULLPTR) // Not present. + if (s == nullptr) // Not present. return false; } @@ -903,7 +903,7 @@ bool RegularExpression::find(char const* string, s = string; if (this->regstart != '\0') // We know what char it must start with. - while ((s = strchr(s, this->regstart)) != KWSYS_NULLPTR) { + while ((s = strchr(s, this->regstart)) != nullptr) { if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program)) return true; s++; @@ -937,8 +937,8 @@ int RegExpFind::regtry(const char* string, const char** start, sp1 = start; ep = end; for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) { - *sp1++ = KWSYS_NULLPTR; - *ep++ = KWSYS_NULLPTR; + *sp1++ = nullptr; + *ep++ = nullptr; } if (regmatch(prog + 1)) { start[0] = string; @@ -966,7 +966,7 @@ int RegExpFind::regmatch(const char* prog) scan = prog; - while (scan != KWSYS_NULLPTR) { + while (scan != nullptr) { next = regnext(scan); @@ -998,14 +998,12 @@ int RegExpFind::regmatch(const char* prog) reginput += len; } break; case ANYOF: - if (*reginput == '\0' || - strchr(OPERAND(scan), *reginput) == KWSYS_NULLPTR) + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == nullptr) return (0); reginput++; break; case ANYBUT: - if (*reginput == '\0' || - strchr(OPERAND(scan), *reginput) != KWSYS_NULLPTR) + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != nullptr) return (0); reginput++; break; @@ -1034,7 +1032,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set startp if some later invocation of the // same parentheses already has. // - if (regstartp[no] == KWSYS_NULLPTR) + if (regstartp[no] == nullptr) regstartp[no] = save; return (1); } else @@ -1062,7 +1060,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set endp if some later invocation of the // same parentheses already has. // - if (regendp[no] == KWSYS_NULLPTR) + if (regendp[no] == nullptr) regendp[no] = save; return (1); } else @@ -1082,7 +1080,7 @@ int RegExpFind::regmatch(const char* prog) return (1); reginput = save; scan = regnext(scan); - } while (scan != KWSYS_NULLPTR && OP(scan) == BRANCH); + } while (scan != nullptr && OP(scan) == BRANCH); return (0); // NOTREACHED } @@ -1160,13 +1158,13 @@ int RegExpFind::regrepeat(const char* p) } break; case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != KWSYS_NULLPTR) { + while (*scan != '\0' && strchr(opnd, *scan) != nullptr) { count++; scan++; } break; case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == KWSYS_NULLPTR) { + while (*scan != '\0' && strchr(opnd, *scan) == nullptr) { count++; scan++; } @@ -1188,11 +1186,11 @@ static const char* regnext(const char* p) int offset; if (p == regdummyptr) - return (KWSYS_NULLPTR); + return (nullptr); offset = NEXT(p); if (offset == 0) - return (KWSYS_NULLPTR); + return (nullptr); if (OP(p) == BACK) return (p - offset); @@ -1205,11 +1203,11 @@ static char* regnext(char* p) int offset; if (p == regdummyptr) - return (KWSYS_NULLPTR); + return (nullptr); offset = NEXT(p); if (offset == 0) - return (KWSYS_NULLPTR); + return (nullptr); if (OP(p) == BACK) return (p - offset); diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in index ed86418..df7eb45 100644 --- a/Source/kwsys/RegularExpression.hxx.in +++ b/Source/kwsys/RegularExpression.hxx.in @@ -71,9 +71,9 @@ private: */ inline RegularExpressionMatch::RegularExpressionMatch() { - startp[0] = 0; - endp[0] = 0; - searchstring = 0; + startp[0] = nullptr; + endp[0] = nullptr; + searchstring = nullptr; } /** @@ -81,7 +81,7 @@ inline RegularExpressionMatch::RegularExpressionMatch() */ inline bool RegularExpressionMatch::isValid() const { - return (this->startp[0] != 0); + return (this->startp[0] != nullptr); } /** @@ -89,9 +89,9 @@ inline bool RegularExpressionMatch::isValid() const */ inline void RegularExpressionMatch::clear() { - startp[0] = 0; - endp[0] = 0; - searchstring = 0; + startp[0] = nullptr; + endp[0] = nullptr; + searchstring = nullptr; } /** @@ -135,7 +135,7 @@ inline std::string::size_type RegularExpressionMatch::end(int n) const */ inline std::string RegularExpressionMatch::match(int n) const { - if (this->startp[n] == 0) { + if (this->startp[n] == nullptr) { return std::string(); } else { return std::string( @@ -230,10 +230,11 @@ inline std::string RegularExpressionMatch::match(int n) const * into the object's private data fields. The == and != operators only check * the to see if the compiled regular expression is the same, and the * deep_equal functions also checks to see if the start and end pointers are - * the same. The is_valid function returns false if program is set to NULL, - * (i.e. there is no valid compiled expression). The set_invalid function - * sets the program to NULL (Warning: this deletes the compiled expression). - * The following examples may help clarify regular expression usage: + * the same. The is_valid function returns false if program is set to + * nullptr, (i.e. there is no valid compiled expression). The set_invalid + * function sets the program to nullptr (Warning: this deletes the compiled + * expression). The following examples may help clarify regular expression + * usage: * * * The regular expression "^hello" matches a "hello" only at the * beginning of a line. It would match "hello there" but not "hi, @@ -288,7 +289,7 @@ class @KWSYS_NAMESPACE@_EXPORT RegularExpression { public: /** - * Instantiate RegularExpression with program=NULL. + * Instantiate RegularExpression with program=nullptr. */ inline RegularExpression(); @@ -410,7 +411,7 @@ inline RegularExpression::RegularExpression() : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { } @@ -423,7 +424,7 @@ inline RegularExpression::RegularExpression(const char* s) : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { if (s) { @@ -439,7 +440,7 @@ inline RegularExpression::RegularExpression(const std::string& s) : regstart{} , reganch{} , regmust{} - , program{ 0 } + , program{ nullptr } , progsize{} { this->compile(s); @@ -545,7 +546,7 @@ inline bool RegularExpression::operator!=(const RegularExpression& r) const */ inline bool RegularExpression::is_valid() const { - return (this->program != 0); + return (this->program != nullptr); } inline void RegularExpression::set_invalid() @@ -553,7 +554,7 @@ inline void RegularExpression::set_invalid() //#ifndef _WIN32 delete[] this->program; //#endif - this->program = 0; + this->program = nullptr; } } // namespace @KWSYS_NAMESPACE@ diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 7dc6cf4..6ec6e48 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -847,31 +847,16 @@ void SystemInformation::RunMemoryCheck() // SystemInformationImplementation starts here -#define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x -#define TLBCACHE_INFO_UNITS (15) -#define CLASSICAL_CPU_FREQ_LOOP 10000000 -#define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 - -// Status Flag -#define HT_NOT_CAPABLE 0 -#define HT_ENABLED 1 -#define HT_DISABLED 2 -#define HT_SUPPORTED_NOT_ENABLED 3 -#define HT_CANNOT_DETECT 4 - -// EDX[28] Bit 28 is set if HT is supported -#define HT_BIT 0x10000000 - -// EAX[11:8] Bit 8-11 contains family processor ID. -#define FAMILY_ID 0x0F00 -#define PENTIUM4_ID 0x0F00 -// EAX[23:20] Bit 20-23 contains extended family processor ID -#define EXT_FAMILY_ID 0x0F00000 -// EBX[23:16] Bit 16-23 in ebx contains the number of logical -#define NUM_LOGICAL_BITS 0x00FF0000 -// processors per physical processor when execute cpuid with -// eax set to 1 -// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique +#if USE_CPUID +# define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x +# define TLBCACHE_INFO_UNITS (15) +#endif + +#if USE_ASM_INSTRUCTIONS +# define CLASSICAL_CPU_FREQ_LOOP 10000000 +# define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 +#endif + #define INITIAL_APIC_ID_BITS 0xFF000000 // initial APIC ID for the processor this code is running on. // Default value = 0xff if HT is not supported @@ -888,7 +873,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines) char buf[bufSize] = { '\0' }; while (!feof(file) && !ferror(file)) { errno = 0; - if (fgets(buf, bufSize, file) == KWSYS_NULLPTR) { + if (fgets(buf, bufSize, file) == nullptr) { if (ferror(file) && (errno == EINTR)) { clearerr(file); } @@ -952,7 +937,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) return -1; } int i = 0; - while (fieldNames[i] != NULL) { + while (fieldNames[i] != nullptr) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -966,7 +951,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) template <typename T> int GetFieldFromFile(const char* fileName, const char* fieldName, T& value) { - const char* fieldNames[2] = { fieldName, NULL }; + const char* fieldNames[2] = { fieldName, nullptr }; T values[1] = { T(0) }; int ierr = GetFieldsFromFile(fileName, fieldNames, values); if (ierr) { @@ -984,7 +969,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, T* values) { FILE* file = popen(command, "r"); - if (file == KWSYS_NULLPTR) { + if (file == nullptr) { return -1; } std::vector<std::string> fields; @@ -994,7 +979,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, return -1; } int i = 0; - while (fieldNames[i] != KWSYS_NULLPTR) { + while (fieldNames[i] != nullptr) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -1030,8 +1015,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGFPE: - oss << "Caught SIGFPE at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGFPE at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { # if defined(FPE_INTDIV) @@ -1079,8 +1063,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGSEGV: - oss << "Caught SIGSEGV at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGSEGV at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case SEGV_MAPERR: @@ -1098,8 +1081,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGBUS: - oss << "Caught SIGBUS at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGBUS at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case BUS_ADRALN: @@ -1139,8 +1121,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGILL: - oss << "Caught SIGILL at " - << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "") + oss << "Caught SIGILL at " << (sigInfo->si_addr == nullptr ? "0x" : "") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case ILL_ILLOPC: @@ -1324,8 +1305,8 @@ SymbolProperties::SymbolProperties() // not using an initializer list // to avoid some PGI compiler warnings this->SetBinary("???"); - this->SetBinaryBaseAddress(KWSYS_NULLPTR); - this->Address = KWSYS_NULLPTR; + this->SetBinaryBaseAddress(nullptr); + this->Address = nullptr; this->SetSourceFile("???"); this->SetFunction("???"); this->SetLineNumber(-1); @@ -1682,7 +1663,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( return -2; } - for (ifa = ifas; ifa != KWSYS_NULLPTR; ifa = ifa->ifa_next) { + for (ifa = ifas; ifa != nullptr; ifa = ifa->ifa_next) { int fam = ifa->ifa_addr ? ifa->ifa_addr->sa_family : -1; // Skip Loopback interfaces if (((fam == AF_INET) || (fam == AF_INET6)) && @@ -1693,7 +1674,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( : sizeof(struct sockaddr_in6)); ierr = getnameinfo(ifa->ifa_addr, static_cast<socklen_t>(addrlen), host, - NI_MAXHOST, KWSYS_NULLPTR, 0, NI_NAMEREQD); + NI_MAXHOST, nullptr, 0, NI_NAMEREQD); if (ierr) { // don't report the failure now since we may succeed on another // interface. If all attempts fail then return the failure code. @@ -2577,7 +2558,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() // If RDTSC is not supported, we fallback to trying to read this value // from the registry: if (!retrieved) { - HKEY hKey = NULL; + HKEY hKey = nullptr; LONG err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, @@ -2597,7 +2578,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() } RegCloseKey(hKey); - hKey = NULL; + hKey = nullptr; } } #endif @@ -3628,7 +3609,7 @@ SystemInformationImplementation::GetHostMemoryTotal() #elif defined(__APPLE__) uint64_t mem; size_t len = sizeof(mem); - int ierr = sysctlbyname("hw.memsize", &mem, &len, KWSYS_NULLPTR, 0); + int ierr = sysctlbyname("hw.memsize", &mem, &len, nullptr, 0); if (ierr) { return -1; } @@ -3745,12 +3726,12 @@ SystemInformationImplementation::GetHostMemoryUsed() # endif #elif defined(__linux) // First try to use MemAvailable, but it only works on newer kernels - const char* names2[3] = { "MemTotal:", "MemAvailable:", NULL }; + const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr }; SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) }; int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2); if (ierr) { const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:", - NULL }; + nullptr }; SystemInformation::LongLong values4[4] = { SystemInformation::LongLong( 0) }; ierr = GetFieldsFromFile("/proc/meminfo", names4, values4); @@ -3771,8 +3752,7 @@ SystemInformationImplementation::GetHostMemoryUsed() if (psz < 1) { return -1; } - const char* names[3] = { "Pages wired down:", "Pages active:", - KWSYS_NULLPTR }; + const char* names[3] = { "Pages wired down:", "Pages active:", nullptr }; SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) }; int ierr = GetFieldsFromCommand("vm_stat", names, values); if (ierr) { @@ -3820,7 +3800,7 @@ SystemInformationImplementation::GetProcMemoryUsed() std::ostringstream oss; oss << "ps -o rss= -p " << pid; FILE* file = popen(oss.str().c_str(), "r"); - if (file == KWSYS_NULLPTR) { + if (file == nullptr) { return -1; } oss.str(""); @@ -3920,9 +3900,9 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame, void* stack[TRACE_MAX_STACK_FRAMES]; HANDLE process = GetCurrentProcess(); - SymInitialize(process, NULL, TRUE); + SymInitialize(process, nullptr, TRUE); WORD numberOfFrames = - CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, NULL); + CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, nullptr); SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>( malloc(sizeof(SYMBOL_INFO) + (TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR))); @@ -3933,7 +3913,7 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame, line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); for (int i = 0; i < numberOfFrames; i++) { DWORD64 address = reinterpret_cast<DWORD64>(stack[i]); - SymFromAddr(process, address, NULL, symbol); + SymFromAddr(process, address, nullptr, symbol); if (SymGetLineFromAddr64(process, address, &displacement, &line)) { oss << " at " << symbol->Name << " in " << line.FileName << " line " << line.LineNumber << std::endl; @@ -4000,13 +3980,13 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable) if (enable && !saOrigValid) { // save the current actions - sigaction(SIGABRT, KWSYS_NULLPTR, &saABRTOrig); - sigaction(SIGSEGV, KWSYS_NULLPTR, &saSEGVOrig); - sigaction(SIGTERM, KWSYS_NULLPTR, &saTERMOrig); - sigaction(SIGINT, KWSYS_NULLPTR, &saINTOrig); - sigaction(SIGILL, KWSYS_NULLPTR, &saILLOrig); - sigaction(SIGBUS, KWSYS_NULLPTR, &saBUSOrig); - sigaction(SIGFPE, KWSYS_NULLPTR, &saFPEOrig); + sigaction(SIGABRT, nullptr, &saABRTOrig); + sigaction(SIGSEGV, nullptr, &saSEGVOrig); + sigaction(SIGTERM, nullptr, &saTERMOrig); + sigaction(SIGINT, nullptr, &saINTOrig); + sigaction(SIGILL, nullptr, &saILLOrig); + sigaction(SIGBUS, nullptr, &saBUSOrig); + sigaction(SIGFPE, nullptr, &saFPEOrig); // enable read, disable write saOrigValid = 1; @@ -4020,22 +4000,22 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable) # endif sigemptyset(&sa.sa_mask); - sigaction(SIGABRT, &sa, KWSYS_NULLPTR); - sigaction(SIGSEGV, &sa, KWSYS_NULLPTR); - sigaction(SIGTERM, &sa, KWSYS_NULLPTR); - sigaction(SIGINT, &sa, KWSYS_NULLPTR); - sigaction(SIGILL, &sa, KWSYS_NULLPTR); - sigaction(SIGBUS, &sa, KWSYS_NULLPTR); - sigaction(SIGFPE, &sa, KWSYS_NULLPTR); + sigaction(SIGABRT, &sa, nullptr); + sigaction(SIGSEGV, &sa, nullptr); + sigaction(SIGTERM, &sa, nullptr); + sigaction(SIGINT, &sa, nullptr); + sigaction(SIGILL, &sa, nullptr); + sigaction(SIGBUS, &sa, nullptr); + sigaction(SIGFPE, &sa, nullptr); } else if (!enable && saOrigValid) { // restore previous actions - sigaction(SIGABRT, &saABRTOrig, KWSYS_NULLPTR); - sigaction(SIGSEGV, &saSEGVOrig, KWSYS_NULLPTR); - sigaction(SIGTERM, &saTERMOrig, KWSYS_NULLPTR); - sigaction(SIGINT, &saINTOrig, KWSYS_NULLPTR); - sigaction(SIGILL, &saILLOrig, KWSYS_NULLPTR); - sigaction(SIGBUS, &saBUSOrig, KWSYS_NULLPTR); - sigaction(SIGFPE, &saFPEOrig, KWSYS_NULLPTR); + sigaction(SIGABRT, &saABRTOrig, nullptr); + sigaction(SIGSEGV, &saSEGVOrig, nullptr); + sigaction(SIGTERM, &saTERMOrig, nullptr); + sigaction(SIGINT, &saINTOrig, nullptr); + sigaction(SIGILL, &saILLOrig, nullptr); + sigaction(SIGBUS, &saBUSOrig, nullptr); + sigaction(SIGFPE, &saFPEOrig, nullptr); // enable write, disable read saOrigValid = 0; @@ -4417,7 +4397,7 @@ void SystemInformationImplementation::CPUCountWindows() std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo; { DWORD Length = 0; - DWORD rc = pGetLogicalProcessorInformation(NULL, &Length); + DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length); assert(FALSE == rc); (void)rc; // Silence unused variable warning in Borland C++ 5.81 assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); @@ -4471,7 +4451,7 @@ bool SystemInformationImplementation::ParseSysCtl() int err = 0; uint64_t value = 0; size_t len = sizeof(value); - sysctlbyname("hw.memsize", &value, &len, KWSYS_NULLPTR, 0); + sysctlbyname("hw.memsize", &value, &len, nullptr, 0); this->TotalPhysicalMemory = static_cast<size_t>(value / 1048576); // Parse values for Mac @@ -4481,7 +4461,7 @@ bool SystemInformationImplementation::ParseSysCtl() if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) == KERN_SUCCESS) { len = sizeof(value); - err = sysctlbyname("hw.pagesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.pagesize", &value, &len, nullptr, 0); int64_t available_memory = (vmstat.free_count + vmstat.inactive_count) * value; this->AvailablePhysicalMemory = @@ -4491,10 +4471,11 @@ bool SystemInformationImplementation::ParseSysCtl() # ifdef VM_SWAPUSAGE // Virtual memory. int mib[2] = { CTL_VM, VM_SWAPUSAGE }; - size_t miblen = sizeof(mib) / sizeof(mib[0]); + unsigned int miblen = + static_cast<unsigned int>(sizeof(mib) / sizeof(mib[0])); struct xsw_usage swap; len = sizeof(swap); - err = sysctl(mib, miblen, &swap, &len, KWSYS_NULLPTR, 0); + err = sysctl(mib, miblen, &swap, &len, nullptr, 0); if (err == 0) { this->AvailableVirtualMemory = static_cast<size_t>(swap.xsu_avail / 1048576); @@ -4507,75 +4488,72 @@ bool SystemInformationImplementation::ParseSysCtl() // CPU Info len = sizeof(this->NumberOfPhysicalCPU); - sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, - KWSYS_NULLPTR, 0); + sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, nullptr, 0); len = sizeof(this->NumberOfLogicalCPU); - sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, KWSYS_NULLPTR, - 0); + sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, nullptr, 0); int cores_per_package = 0; len = sizeof(cores_per_package); err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len, - KWSYS_NULLPTR, 0); + nullptr, 0); // That name was not found, default to 1 this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = err != 0 ? 1 : static_cast<unsigned char>(cores_per_package); len = sizeof(value); - sysctlbyname("hw.cpufrequency", &value, &len, KWSYS_NULLPTR, 0); + sysctlbyname("hw.cpufrequency", &value, &len, nullptr, 0); this->CPUSpeedInMHz = static_cast<float>(value) / 1000000; // Chip family len = sizeof(this->ChipID.Family); // Seems only the intel chips will have this name so if this fails it is // probably a PPC machine - err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + err = + sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, nullptr, 0); if (err != 0) // Go back to names we know but are less descriptive { this->ChipID.Family = 0; ::memset(retBuf, 0, 128); len = 32; - err = sysctlbyname("hw.machine", &retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.machine", &retBuf, &len, nullptr, 0); std::string machineBuf(retBuf); if (machineBuf.find_first_of("Power") != std::string::npos) { this->ChipID.Vendor = "IBM"; len = sizeof(this->ChipID.Family); - err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, nullptr, 0); len = sizeof(this->ChipID.Model); - err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, - KWSYS_NULLPTR, 0); + err = + sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, nullptr, 0); this->FindManufacturer(); } } else // Should be an Intel Chip. { len = sizeof(this->ChipID.Family); err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, - KWSYS_NULLPTR, 0); + nullptr, 0); ::memset(retBuf, 0, 128); len = 128; - err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, nullptr, 0); // Chip Vendor this->ChipID.Vendor = retBuf; this->FindManufacturer(); // Chip Model len = sizeof(value); - err = sysctlbyname("machdep.cpu.model", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.model", &value, &len, nullptr, 0); this->ChipID.Model = static_cast<int>(value); // Chip Stepping len = sizeof(value); value = 0; - err = sysctlbyname("machdep.cpu.stepping", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.stepping", &value, &len, nullptr, 0); if (!err) { this->ChipID.Revision = static_cast<int>(value); } // feature string - char* buf = KWSYS_NULLPTR; + char* buf = nullptr; size_t allocSize = 128; err = 0; @@ -4592,8 +4570,7 @@ bool SystemInformationImplementation::ParseSysCtl() } buf[0] = ' '; len = allocSize - 2; // keep space for leading and trailing space - err = - sysctlbyname("machdep.cpu.features", buf + 1, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.features", buf + 1, &len, nullptr, 0); } if (!err && buf && len) { // now we can match every flags as space + flag + space @@ -4634,8 +4611,7 @@ bool SystemInformationImplementation::ParseSysCtl() // brand string ::memset(retBuf, 0, sizeof(retBuf)); len = sizeof(retBuf); - err = - sysctlbyname("machdep.cpu.brand_string", retBuf, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, nullptr, 0); if (!err) { this->ChipID.ProcessorName = retBuf; this->ChipID.ModelName = retBuf; @@ -4643,10 +4619,10 @@ bool SystemInformationImplementation::ParseSysCtl() // Cache size len = sizeof(value); - err = sysctlbyname("hw.l1icachesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.l1icachesize", &value, &len, nullptr, 0); this->Features.L1CacheSize = static_cast<int>(value); len = sizeof(value); - err = sysctlbyname("hw.l2cachesize", &value, &len, KWSYS_NULLPTR, 0); + err = sysctlbyname("hw.l2cachesize", &value, &len, nullptr, 0); this->Features.L2CacheSize = static_cast<int>(value); return true; @@ -4683,7 +4659,7 @@ std::string SystemInformationImplementation::RunProcess( kwsysProcess_Execute(gp); - char* data = KWSYS_NULLPTR; + char* data = nullptr; int length; double timeout = 255; int pipe; // pipe id as returned by kwsysProcess_WaitForData() @@ -4695,7 +4671,7 @@ std::string SystemInformationImplementation::RunProcess( { buffer.append(data, length); } - kwsysProcess_WaitForExit(gp, KWSYS_NULLPTR); + kwsysProcess_WaitForExit(gp, nullptr); int result = 0; switch (kwsysProcess_GetState(gp)) { @@ -4766,7 +4742,7 @@ std::string SystemInformationImplementation::ParseValueFromKStat( for (size_t i = 0; i < args_string.size(); ++i) { args.push_back(args_string[i].c_str()); } - args.push_back(KWSYS_NULLPTR); + args.push_back(nullptr); std::string buffer = this->RunProcess(args); @@ -4965,7 +4941,7 @@ bool SystemInformationImplementation::QueryBSDMemory() # endif size_t sz = sizeof(k); - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5036,7 +5012,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() size_t sz = sizeof(k); int ctrl[2] = { CTL_HW, HW_NCPU }; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5046,7 +5022,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() # if defined(HW_CPUSPEED) ctrl[1] = HW_CPUSPEED; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5057,7 +5033,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() ctrl[0] = CTL_MACHDEP; ctrl[1] = CPU_SSE; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5068,7 +5044,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() ctrl[0] = CTL_MACHDEP; ctrl[1] = CPU_SSE2; - if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { return false; } @@ -5081,7 +5057,7 @@ bool SystemInformationImplementation::QueryBSDProcessor() char vbuf[25]; ::memset(vbuf, 0, sizeof(vbuf)); sz = sizeof(vbuf) - 1; - if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0) { + if (sysctl(ctrl, 2, vbuf, &sz, nullptr, 0) != 0) { return false; } @@ -5293,7 +5269,7 @@ bool SystemInformationImplementation::QueryOSInformation() RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); - RegQueryValueExW(hKey, L"ProductType", NULL, NULL, + RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, (LPBYTE)szProductType, &dwBufLen); RegCloseKey(hKey); @@ -5335,13 +5311,13 @@ bool SystemInformationImplementation::QueryOSInformation() // Load the Kernel32 DLL. hKernelDLL = LoadLibraryW(L"kernel32"); - if (hKernelDLL != NULL) { + if (hKernelDLL != nullptr) { // Only XP and .NET Server support IsWOW64Process so... Load // dynamically! DLLProc = (LPFNPROC)GetProcAddress(hKernelDLL, "IsWow64Process"); // If the function address is valid, call the function. - if (DLLProc != NULL) + if (DLLProc != nullptr) (DLLProc)(GetCurrentProcess(), &bIsWindows64Bit); else bIsWindows64Bit = false; @@ -5456,7 +5432,7 @@ int SystemInformationImplementation::CallSwVers(const char* arg, std::vector<const char*> args; args.push_back("sw_vers"); args.push_back(arg); - args.push_back(KWSYS_NULLPTR); + args.push_back(nullptr); ver = this->RunProcess(args); this->TrimNewline(ver); #else diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index 5e93878..fc42e9d 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -115,8 +115,8 @@ public: // returns an informative general description if the installed and // available ram on this system. See the GetHostMemoryTotal, and // Get{Host,Proc}MemoryAvailable methods for more information. - std::string GetMemoryDescription(const char* hostLimitEnvVarName = NULL, - const char* procLimitEnvVarName = NULL); + std::string GetMemoryDescription(const char* hostLimitEnvVarName = nullptr, + const char* procLimitEnvVarName = nullptr); // Retrieve amount of physical memory installed on the system in KiB // units. @@ -128,7 +128,7 @@ public: // parallel. The amount of memory reported may differ from the host // total if a host wide resource limit is applied. Such reource limits // are reported to us via an application specified environment variable. - LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = NULL); + LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr); // Get total system RAM in units of KiB available to this process. // This may differ from the host available if a per-process resource @@ -136,8 +136,8 @@ public: // system via rlimit API. Resource limits that are not imposed via // rlimit API may be reported to us via an application specified // environment variable. - LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = NULL, - const char* procLimitEnvVarName = NULL); + LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr, + const char* procLimitEnvVarName = nullptr); // Get the system RAM used by all processes on the host, in units of KiB. LongLong GetHostMemoryUsed(); diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 8571477..ce4d6ef 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -192,15 +192,15 @@ static inline char* realpath(const char* path, char* resolved_path) { const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH; snprintf(resolved_path, maxlen, "%s", path); - BPath normalized(resolved_path, NULL, true); + BPath normalized(resolved_path, nullptr, true); const char* resolved = normalized.Path(); - if (resolved != NULL) // NULL == No such file. + if (resolved != nullptr) // nullptr == No such file. { if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) { return resolved_path; } } - return NULL; // something went wrong. + return nullptr; // something went wrong. } #endif @@ -273,12 +273,12 @@ inline void Realpath(const std::string& path, std::string& resolved_path, if (bufferLen) { *errorMessage = "Destination path buffer size too small."; } else if (unsigned int errorId = GetLastError()) { - LPSTR message = NULL; + LPSTR message = nullptr; DWORD size = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&message, 0, NULL); + nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, nullptr); *errorMessage = std::string(message, size); LocalFree(message); } else { @@ -313,7 +313,7 @@ inline int Chdir(const std::string& dir) return chdir(dir.c_str()); } inline void Realpath(const std::string& path, std::string& resolved_path, - std::string* errorMessage = KWSYS_NULLPTR) + std::string* errorMessage = nullptr) { char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH]; @@ -359,7 +359,7 @@ double SystemTools::GetTime(void) 11644473600.0); #else struct timeval t; - gettimeofday(&t, KWSYS_NULLPTR); + gettimeofday(&t, nullptr); return 1.0 * double(t.tv_sec) + 0.000001 * double(t.tv_usec); #endif } @@ -389,8 +389,8 @@ struct kwsysEnvCompare #else const char* leq = strchr(l, '='); const char* req = strchr(r, '='); - size_t llen = leq ? (leq - l) : strlen(l); - size_t rlen = req ? (req - r) : strlen(r); + size_t llen = leq ? static_cast<size_t>(leq - l) : strlen(l); + size_t rlen = req ? static_cast<size_t>(req - r) : strlen(r); if (llen == rlen) { return strncmp(l, r, llen) < 0; } else { @@ -420,7 +420,7 @@ public: const envchar* Release(const envchar* env) { - const envchar* old = KWSYS_NULLPTR; + const envchar* old = nullptr; iterator i = this->find(env); if (i != this->end()) { old = *i; @@ -630,7 +630,7 @@ const char* SystemToolsStatic::GetEnvBuffered(const char* key) } return menv.c_str(); } - return KWSYS_NULLPTR; + return nullptr; } #endif @@ -684,7 +684,7 @@ bool SystemTools::HasEnv(const char* key) #else const char* v = getenv(key); #endif - return v != KWSYS_NULLPTR; + return v != nullptr; } bool SystemTools::HasEnv(const std::string& key) @@ -915,7 +915,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) while ((pos = dir.find('/', pos)) != std::string::npos) { topdir = dir.substr(0, pos); - if (Mkdir(topdir) == 0 && mode != KWSYS_NULLPTR) { + if (Mkdir(topdir) == 0 && mode != nullptr) { SystemTools::SetPermissions(topdir, *mode); } @@ -934,7 +934,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) ) { return false; } - } else if (mode != KWSYS_NULLPTR) { + } else if (mode != nullptr) { SystemTools::SetPermissions(topdir, *mode); } @@ -1055,7 +1055,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode, // only add the modes when on a system that supports Wow64. static FARPROC wow64p = GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); - if (wow64p == NULL) { + if (wow64p == nullptr) { return mode; } @@ -1136,7 +1136,7 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value, DWORD dwType, dwSize; dwSize = 1023; wchar_t data[1024]; - if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), NULL, + if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), nullptr, &dwType, (BYTE*)data, &dwSize) == ERROR_SUCCESS) { if (dwType == REG_SZ) { value = Encoding::ToNarrow(data); @@ -1186,7 +1186,7 @@ bool SystemTools::WriteRegistryValue(const std::string& key, wchar_t lpClass[] = L""; if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass, REG_OPTION_NON_VOLATILE, - SystemToolsMakeRegistryMode(KEY_WRITE, view), NULL, + SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr, &hKey, &dwDummy) != ERROR_SUCCESS) { return false; } @@ -1252,10 +1252,10 @@ bool SystemTools::SameFile(const std::string& file1, const std::string& file2) hFile1 = CreateFileW(Encoding::ToWide(file1).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); hFile2 = CreateFileW(Encoding::ToWide(file2).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE) { if (hFile1 != INVALID_HANDLE_VALUE) { CloseHandle(hFile1); @@ -1347,7 +1347,7 @@ bool SystemTools::FileExists(const std::string& filename) // even if we do not have permission to read the file itself HANDLE handle = CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(), 0, 0, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (handle == INVALID_HANDLE_VALUE) { return false; @@ -1493,12 +1493,12 @@ bool SystemTools::Touch(const std::string& filename, bool create) CloseHandle(h); #elif KWSYS_CXX_HAS_UTIMENSAT // utimensat is only available on newer Unixes and macOS 10.13+ - if (utimensat(AT_FDCWD, filename.c_str(), NULL, 0) < 0) { + if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) { return false; } #else // fall back to utimes - if (utimes(filename.c_str(), NULL) < 0) { + if (utimes(filename.c_str(), nullptr) < 0) { return false; } #endif @@ -1653,7 +1653,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2) size_t len1 = strlen(str1); char* newstr = new char[len1 + strlen(str2) + 1]; if (!newstr) { - return KWSYS_NULLPTR; + return nullptr; } strcpy(newstr, str1); strcat(newstr + len1, str2); @@ -1676,7 +1676,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2, size_t len1 = strlen(str1), len2 = strlen(str2); char* newstr = new char[len1 + len2 + strlen(str3) + 1]; if (!newstr) { - return KWSYS_NULLPTR; + return nullptr; } strcpy(newstr, str1); strcat(newstr + len1, str2); @@ -1726,7 +1726,7 @@ size_t SystemTools::CountChar(const char* str, char c) char* SystemTools::RemoveChars(const char* str, const char* toremove) { if (!str) { - return KWSYS_NULLPTR; + return nullptr; } char* clean_str = new char[strlen(str) + 1]; char* ptr = clean_str; @@ -1748,7 +1748,7 @@ char* SystemTools::RemoveChars(const char* str, const char* toremove) char* SystemTools::RemoveCharsButUpperHex(const char* str) { if (!str) { - return KWSYS_NULLPTR; + return nullptr; } char* clean_str = new char[strlen(str) + 1]; char* ptr = clean_str; @@ -1829,7 +1829,7 @@ bool SystemTools::StringEndsWith(const std::string& str1, const char* str2) const char* SystemTools::FindLastString(const char* str1, const char* str2) { if (!str1 || !str2) { - return KWSYS_NULLPTR; + return nullptr; } size_t len1 = strlen(str1), len2 = strlen(str2); @@ -1842,7 +1842,7 @@ const char* SystemTools::FindLastString(const char* str1, const char* str2) } while (ptr-- != str1); } - return KWSYS_NULLPTR; + return nullptr; } // Duplicate string @@ -1852,7 +1852,7 @@ char* SystemTools::DuplicateString(const char* str) char* newstr = new char[strlen(str) + 1]; return strcpy(newstr, str); } - return KWSYS_NULLPTR; + return nullptr; } // Return a cropped string @@ -3018,16 +3018,16 @@ bool SystemTools::FileIsSymlink(const std::string& name) // * a file or directory that has an associated reparse point, or // * a file that is a symbolic link. HANDLE hFile = CreateFileW( - path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); + path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return false; } byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; DWORD bytesReturned = 0; - if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, + if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, - NULL)) { + nullptr)) { CloseHandle(hFile); // Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be // a symbolic link if it is not a reparse point. @@ -3058,7 +3058,7 @@ bool SystemTools::FileIsFIFO(const std::string& name) #if defined(_WIN32) HANDLE hFile = CreateFileW(Encoding::ToWide(name).c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return false; } @@ -3219,7 +3219,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut, std::string SystemTools::CollapseFullPath(const std::string& in_relative) { - return SystemTools::CollapseFullPath(in_relative, KWSYS_NULLPTR); + return SystemTools::CollapseFullPath(in_relative, nullptr); } #if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP @@ -4013,7 +4013,7 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) } std::wstring wtempPath = Encoding::ToWide(tempPath); - DWORD ret = GetShortPathNameW(wtempPath.c_str(), NULL, 0); + DWORD ret = GetShortPathNameW(wtempPath.c_str(), nullptr, 0); std::vector<wchar_t> buffer(ret); if (ret != 0) { ret = GetShortPathNameW(wtempPath.c_str(), &buffer[0], @@ -4421,7 +4421,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion() return 0; } - lRet = RegQueryValueExW(hKey, L"ProductType", NULL, NULL, + lRet = RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, (LPBYTE)szProductType, &dwBufLen); if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE)) { diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index dd1266b..c4ab9d4 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -400,9 +400,10 @@ public: * installPrefix is a possibly null pointer to the install directory. */ static bool FindProgramPath(const char* argv0, std::string& pathOut, - std::string& errorMsg, const char* exeName = 0, - const char* buildDir = 0, - const char* installPrefix = 0); + std::string& errorMsg, + const char* exeName = nullptr, + const char* buildDir = nullptr, + const char* installPrefix = nullptr); /** * Given a path to a file or directory, convert it to a full path. @@ -420,11 +421,11 @@ public: * Get the real path for a given path, removing all symlinks. In * the event of an error (non-existent path, permissions issue, * etc.) the original path is returned if errorMessage pointer is - * NULL. Otherwise empty string is returned and errorMessage + * nullptr. Otherwise empty string is returned and errorMessage * contains error description. */ static std::string GetRealPath(const std::string& path, - std::string* errorMessage = 0); + std::string* errorMessage = nullptr); /** * Split a path name into its root component and the rest of the @@ -442,7 +443,7 @@ public: * given. */ static const char* SplitPathRootComponent(const std::string& p, - std::string* root = 0); + std::string* root = nullptr); /** * Split a path name into its basic components. The first component @@ -528,7 +529,8 @@ public: * be true when the line read had a newline character. */ static bool GetLineFromStream(std::istream& istr, std::string& line, - bool* has_newline = 0, long sizeLimit = -1); + bool* has_newline = nullptr, + long sizeLimit = -1); /** * Get the parent directory of the directory or file @@ -563,8 +565,9 @@ public: * can make a full path even if none of the directories existed * prior to calling this function. */ - static bool MakeDirectory(const char* path, const mode_t* mode = 0); - static bool MakeDirectory(const std::string& path, const mode_t* mode = 0); + static bool MakeDirectory(const char* path, const mode_t* mode = nullptr); + static bool MakeDirectory(const std::string& path, + const mode_t* mode = nullptr); /** * Copy the source file to the destination file only @@ -842,7 +845,8 @@ public: * string vector passed in. If env is set then the value * of env will be used instead of PATH. */ - static void GetPath(std::vector<std::string>& path, const char* env = 0); + static void GetPath(std::vector<std::string>& path, + const char* env = nullptr); /** * Read an environment variable diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in index 0981c66..8c4b002 100644 --- a/Source/kwsys/hashtable.hxx.in +++ b/Source/kwsys/hashtable.hxx.in @@ -354,7 +354,7 @@ public: return end(); } - iterator end() { return iterator(0, this); } + iterator end() { return iterator(nullptr, this); } const_iterator begin() const { @@ -364,7 +364,7 @@ public: return end(); } - const_iterator end() const { return const_iterator(0, this); } + const_iterator end() const { return const_iterator(nullptr, this); } friend bool operator==<>(const hashtable&, const hashtable&); @@ -510,7 +510,7 @@ private: { const size_type __n_buckets = _M_next_size(__n); _M_buckets.reserve(__n_buckets); - _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)0); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr); _M_num_elements = 0; } @@ -544,7 +544,7 @@ private: _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); - __n->_M_next = 0; + __n->_M_next = nullptr; try { construct(&__n->_M_val, __obj); return __n; @@ -839,9 +839,9 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { - _M_erase_bucket(__f_bucket, __first._M_cur, 0); + _M_erase_bucket(__f_bucket, __first._M_cur, nullptr); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) - _M_erase_bucket(__n, 0); + _M_erase_bucket(__n, nullptr); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); } @@ -873,7 +873,8 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize( if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { - _M_buckets_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + _M_buckets_type __tmp(__n, (_Node*)(nullptr), + _M_buckets.get_allocator()); try { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; @@ -940,12 +941,12 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() { for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { _Node* __cur = _M_buckets[__i]; - while (__cur != 0) { + while (__cur != nullptr) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } - _M_buckets[__i] = 0; + _M_buckets[__i] = nullptr; } _M_num_elements = 0; } @@ -956,7 +957,7 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from( { _M_buckets.clear(); _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)0); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)nullptr); try { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx index 15f9c02..1778a9b 100644 --- a/Source/kwsys/testCommandLineArguments.cxx +++ b/Source/kwsys/testCommandLineArguments.cxx @@ -76,7 +76,7 @@ int testCommandLineArguments(int argc, char* argv[]) int some_int_variable = 10; double some_double_variable = 10.10; - char* some_string_variable = KWSYS_NULLPTR; + char* some_string_variable = nullptr; std::string some_stl_string_variable; bool some_bool_variable = false; bool some_bool_variable1 = false; @@ -203,7 +203,7 @@ int testCommandLineArguments(int argc, char* argv[]) for (cc = 0; cc < strings_argument.size(); ++cc) { delete[] strings_argument[cc]; - strings_argument[cc] = KWSYS_NULLPTR; + strings_argument[cc] = nullptr; } return res; } diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx index 9895008..64561b1 100644 --- a/Source/kwsys/testCommandLineArguments1.cxx +++ b/Source/kwsys/testCommandLineArguments1.cxx @@ -21,7 +21,7 @@ int testCommandLineArguments1(int argc, char* argv[]) arg.Initialize(argc, argv); int n = 0; - char* m = KWSYS_NULLPTR; + char* m = nullptr; std::string p; int res = 0; @@ -55,11 +55,11 @@ int testCommandLineArguments1(int argc, char* argv[]) delete[] m; } - char** newArgv = KWSYS_NULLPTR; + char** newArgv = nullptr; int newArgc = 0; arg.GetUnusedArguments(&newArgc, &newArgv); int cc; - const char* valid_unused_args[9] = { KWSYS_NULLPTR, + const char* valid_unused_args[9] = { nullptr, "--ignored", "--second-ignored", "third-ignored", diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx index b6ad118..4b7ddf0 100644 --- a/Source/kwsys/testConsoleBuf.cxx +++ b/Source/kwsys/testConsoleBuf.cxx @@ -51,7 +51,7 @@ static void displayError(DWORD errorCode) LPWSTR message; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, 0, (LPWSTR)&message, 0, NULL)) { + nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) { std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl; HeapFree(GetProcessHeap(), 0, message); @@ -124,7 +124,7 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) } WCHAR cmd[MAX_PATH]; - if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) { + if (GetModuleFileNameW(nullptr, cmd, MAX_PATH) == 0) { std::cerr << "GetModuleFileName failed!" << std::endl; return false; } @@ -136,14 +136,14 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) wcscat(cmd, L".exe"); bool success = - CreateProcessW(NULL, // No module name (use command line) + CreateProcessW(nullptr, // No module name (use command line) cmd, // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable bInheritHandles, // Set handle inheritance dwCreationFlags, - NULL, // Use parent's environment block - NULL, // Use parent's starting directory + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory &startupInfo, // Pointer to STARTUPINFO structure &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure @@ -174,7 +174,7 @@ static bool createPipe(PHANDLE readPipe, PHANDLE writePipe) SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false : true; } @@ -194,7 +194,7 @@ static HANDLE createFile(LPCWSTR fileName) SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; HANDLE file = CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE, @@ -202,7 +202,7 @@ static HANDLE createFile(LPCWSTR fileName) &securityAttributes, CREATE_ALWAYS, // overwrite existing FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); // no template + nullptr); // no template if (file == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" @@ -288,7 +288,7 @@ static int testPipe() DWORD bytesWritten = 0; if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(), (DWORD)encodedInputTestString.size(), &bytesWritten, - NULL) || + nullptr) || bytesWritten == 0) { throw std::runtime_error("WriteFile failed!"); } @@ -305,7 +305,8 @@ static int testPipe() throw std::runtime_error("WaitForSingleObject failed!"); } DWORD bytesRead = 0; - if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) || + if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#1 failed!"); } @@ -313,7 +314,7 @@ static int testPipe() if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size() && !ReadFile(outPipeRead, buffer + bytesRead, - sizeof(buffer) - bytesRead, &bytesRead, NULL)) || + sizeof(buffer) - bytesRead, &bytesRead, nullptr)) || bytesRead == 0) { throw std::runtime_error("ReadFile#2 failed!"); } @@ -324,7 +325,7 @@ static int testPipe() encodedInputTestString.size()) == 0) { bytesRead = 0; if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, - NULL) || + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#3 failed!"); } @@ -383,13 +384,13 @@ static int testFile() char buffer2[200]; int length; - if ((length = - WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1, - buffer, sizeof(buffer), NULL, NULL)) == 0) { + if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, + -1, buffer, sizeof(buffer), nullptr, + nullptr)) == 0) { throw std::runtime_error("WideCharToMultiByte failed!"); } buffer[length - 1] = '\n'; - if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL) || + if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) || bytesWritten == 0) { throw std::runtime_error("WriteFile failed!"); } @@ -413,7 +414,7 @@ static int testFile() INVALID_SET_FILE_POINTER) { throw std::runtime_error("SetFilePointer#1 failed!"); } - if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) || + if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#1 failed!"); } @@ -429,7 +430,8 @@ static int testFile() throw std::runtime_error("SetFilePointer#2 failed!"); } - if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL) || + if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, + nullptr) || bytesRead == 0) { throw std::runtime_error("ReadFile#2 failed!"); } @@ -519,12 +521,12 @@ static int testConsole() if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) { DWORD dwordSize = sizeof(DWORD); - if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL, + if (RegQueryValueExW(hConsoleKey, L"FontFamily", nullptr, nullptr, (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) { if (FontFamily != TestFontFamily) { - RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL, + RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr, (LPBYTE)FaceName, &FaceNameSize); - RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL, + RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr, (LPBYTE)&FontSize, &dwordSize); RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD, @@ -557,10 +559,10 @@ static int testConsole() SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.lpSecurityDescriptor = nullptr; hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, nullptr); if (hIn == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(CONIN$)" << std::endl; @@ -568,7 +570,7 @@ static int testConsole() } hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, nullptr); if (hOut == INVALID_HANDLE_VALUE) { DWORD lastError = GetLastError(); std::cerr << "CreateFile(CONOUT$)" << std::endl; @@ -630,7 +632,7 @@ static int testConsole() } # endif - if (createProcess(NULL, NULL, NULL)) { + if (createProcess(nullptr, nullptr, nullptr)) { try { DWORD status; if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != @@ -746,7 +748,7 @@ int testConsoleBuf(int, char* []) int ret = 0; #if defined(_WIN32) - beforeInputEvent = CreateEventW(NULL, + beforeInputEvent = CreateEventW(nullptr, FALSE, // auto-reset event FALSE, // initial state is nonsignaled BeforeInputEventName); // object name @@ -755,7 +757,7 @@ int testConsoleBuf(int, char* []) return 1; } - afterOutputEvent = CreateEventW(NULL, FALSE, FALSE, AfterOutputEventName); + afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName); if (!afterOutputEvent) { std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl; return 1; diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx index eff2ed7..2421ac0 100644 --- a/Source/kwsys/testDynamicLoader.cxx +++ b/Source/kwsys/testDynamicLoader.cxx @@ -21,7 +21,7 @@ // left on disk. #include <testSystemTools.h> -static std::string GetLibName(const char* lname, const char* subdir = NULL) +static std::string GetLibName(const char* lname, const char* subdir = nullptr) { // Construct proper name of lib std::string slname; diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx index fdad1cd..988697b 100644 --- a/Source/kwsys/testEncoding.cxx +++ b/Source/kwsys/testEncoding.cxx @@ -84,7 +84,7 @@ static int testRobustEncoding() // this conversion could fail std::wstring wstr = kwsys::Encoding::ToWide(cstr); - wstr = kwsys::Encoding::ToWide(KWSYS_NULLPTR); + wstr = kwsys::Encoding::ToWide(nullptr); if (wstr != L"") { const wchar_t* wcstr = wstr.c_str(); std::cout << "ToWide(NULL) returned"; @@ -112,7 +112,7 @@ static int testRobustEncoding() std::string win_str = kwsys::Encoding::ToNarrow(cwstr); #endif - std::string str = kwsys::Encoding::ToNarrow(KWSYS_NULLPTR); + std::string str = kwsys::Encoding::ToNarrow(nullptr); if (str != "") { std::cout << "ToNarrow(NULL) returned " << str << std::endl; ret++; diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c index f139f58..39aaa23 100644 --- a/Source/kwsys/testProcess.c +++ b/Source/kwsys/testProcess.c @@ -477,7 +477,7 @@ static int runChild2(kwsysProcess* kp, const char* cmd[], int state, printf("Error in administrating child process: [%s]\n", kwsysProcess_GetErrorString(kp)); break; - }; + } if (result) { if (exception != kwsysProcess_GetExitException(kp)) { diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index 88277de..1f3a15b 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -52,7 +52,7 @@ static const char* toUnixPaths[][2] = { { "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" }, { "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" }, { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo/ cal/bin/pa/ sswd" }, - { KWSYS_NULLPTR, KWSYS_NULLPTR } + { nullptr, nullptr } }; static bool CheckConvertToUnixSlashes(std::string const& input, @@ -71,7 +71,7 @@ static bool CheckConvertToUnixSlashes(std::string const& input, static const char* checkEscapeChars[][4] = { { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2" }, { " {} ", "{}", "#", " #{#} " }, - { KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR } + { nullptr, nullptr, nullptr, nullptr } }; static bool CheckEscapeChars(std::string const& input, @@ -160,7 +160,7 @@ static bool CheckFileOperations() res = false; } // calling with 0 pointer should return false - if (kwsys::SystemTools::MakeDirectory(KWSYS_NULLPTR)) { + if (kwsys::SystemTools::MakeDirectory(nullptr)) { std::cerr << "Problem with MakeDirectory(0)" << std::endl; res = false; } @@ -218,11 +218,11 @@ static bool CheckFileOperations() } // calling with 0 pointer should return false - if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR)) { + if (kwsys::SystemTools::FileExists(nullptr)) { std::cerr << "Problem with FileExists(0)" << std::endl; res = false; } - if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR, true)) { + if (kwsys::SystemTools::FileExists(nullptr, true)) { std::cerr << "Problem with FileExists(0) as file" << std::endl; res = false; } diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in index c58ef71..ad8bfb0 100644 --- a/Templates/TestDriver.cxx.in +++ b/Templates/TestDriver.cxx.in @@ -13,9 +13,15 @@ @CMAKE_FORWARD_DECLARE_TESTS@ #ifdef __cplusplus -#define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR) +# define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR) +# if __cplusplus >= 201103L +# define CM_NULL nullptr +# else +# define CM_NULL NULL +# endif #else -#define CM_CAST(TYPE, EXPR) (TYPE)(EXPR) +# define CM_CAST(TYPE, EXPR) (TYPE)(EXPR) +# define CM_NULL NULL #endif /* Create map. */ @@ -29,7 +35,7 @@ typedef struct /* NOLINT */ static functionMapEntry cmakeGeneratedFunctionMapEntries[] = { @CMAKE_FUNCTION_TABLE_ENTIRES@ - { NULL, NULL } /* NOLINT */ + { CM_NULL, CM_NULL } /* NOLINT */ }; static const int NumTests = CM_CAST(int, @@ -45,8 +51,8 @@ static char* lowercase(const char* string) stringSize = CM_CAST(size_t, strlen(string) + 1); new_string = CM_CAST(char*, malloc(sizeof(char) * stringSize)); - if (new_string == NULL) { /* NOLINT */ - return NULL; /* NOLINT */ + if (new_string == CM_NULL) { /* NOLINT */ + return CM_NULL; /* NOLINT */ } strcpy(new_string, string); for (p = new_string; *p != 0; ++p) { @@ -86,7 +92,7 @@ int main(int ac, char* av[]) av++; } partial_match = 0; - arg = NULL; /* NOLINT */ + arg = CM_NULL; /* NOLINT */ /* If partial match is requested. */ if (testToRun == -1 && ac > 1) { partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; @@ -100,7 +106,7 @@ int main(int ac, char* av[]) } for (i = 0; i < NumTests && testToRun == -1; ++i) { char *test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name); - if (partial_match != 0 && strstr(test_name, arg) != NULL) { /* NOLINT */ + if (partial_match != 0 && strstr(test_name, arg) != CM_NULL) { /* NOLINT */ testToRun = i; ac -= 2; av += 2; diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt index 8e8fa07..729bba3 100644 --- a/Tests/Plugin/CMakeLists.txt +++ b/Tests/Plugin/CMakeLists.txt @@ -10,14 +10,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/plugin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/static) -# We need the dynamic loader support from KWSys to load the plugin in -# the executable. -set(KWSYS_NAMESPACE kwsys) -set(KWSYS_HEADER_ROOT ${Plugin_BINARY_DIR}/include) -set(KWSYS_USE_DynamicLoader 1) -set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8) -add_subdirectory(${Plugin_SOURCE_DIR}/../../Source/kwsys src/kwsys) - # Configure the location of plugins. configure_file(${Plugin_SOURCE_DIR}/src/example_exe.h.in ${Plugin_BINARY_DIR}/include/example_exe.h @ONLY) @@ -36,14 +28,14 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND endif() # Create an executable that exports an API for use by plugins. -add_executable(example_exe src/example_exe.cxx) +add_executable(example_exe src/example_exe.cxx src/DynamicLoader.cxx) set_target_properties(example_exe PROPERTIES ENABLE_EXPORTS 1 OUTPUT_NAME example # Test placing exe import library in unique directory. ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/exe ) -target_link_libraries(example_exe kwsys) +target_link_libraries(example_exe ${CMAKE_DL_LIBS}) # Create a plugin that uses the API provided by the executable. # This module "links" to the executable to use the symbols. diff --git a/Tests/Plugin/include/DynamicLoader.hxx b/Tests/Plugin/include/DynamicLoader.hxx new file mode 100644 index 0000000..20b37de --- /dev/null +++ b/Tests/Plugin/include/DynamicLoader.hxx @@ -0,0 +1,49 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See https://cmake.org/licensing#kwsys for details. */ +#ifndef DynamicLoader_hxx +#define DynamicLoader_hxx + +#include <string> + +#if defined(__hpux) +# include <dl.h> +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> +#elif defined(__APPLE__) +# include <AvailabilityMacros.h> +# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 +# include <mach-o/dyld.h> +# endif +#elif defined(__BEOS__) +# include <be/kernel/image.h> +#endif + +class DynamicLoader +{ +public: +#if defined(__hpux) + typedef shl_t LibraryHandle; +#elif defined(_WIN32) && !defined(__CYGWIN__) + typedef HMODULE LibraryHandle; +#elif defined(__APPLE__) +# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 + typedef NSModule LibraryHandle; +# else + typedef void* LibraryHandle; +# endif +#elif defined(__BEOS__) + typedef image_id LibraryHandle; +#else // POSIX + typedef void* LibraryHandle; +#endif + + typedef void (*SymbolPointer)(); + + static LibraryHandle OpenLibrary(const std::string&); + + static int CloseLibrary(LibraryHandle); + + static SymbolPointer GetSymbolAddress(LibraryHandle, const std::string&); +}; + +#endif diff --git a/Tests/Plugin/src/DynamicLoader.cxx b/Tests/Plugin/src/DynamicLoader.cxx new file mode 100644 index 0000000..d4a2637 --- /dev/null +++ b/Tests/Plugin/src/DynamicLoader.cxx @@ -0,0 +1,263 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See https://cmake.org/licensing#kwsys for details. */ +#if defined(_WIN32) +# define NOMINMAX // hide min,max to not conflict with <limits> +#endif + +#include <DynamicLoader.hxx> + +#if defined(__hpux) +# include <dl.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L); +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (!lib) { + return 0; + } + return !shl_unload(lib); +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* addr; + int status; + + /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default) + * TYPE_DATA Look for a symbol in the data segment (for example, + * variables). + * TYPE_UNDEFINED Look for any symbol. + */ + status = shl_findsym(&lib, sym.c_str(), TYPE_UNDEFINED, &addr); + void* result = (status < 0) ? (void*)0 : addr; + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +} + +#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030) +# include <mach-o/dyld.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + NSObjectFileImageReturnCode rc; + NSObjectFileImage image = 0; + + rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image); + // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file + if (rc != NSObjectFileImageSuccess) { + return 0; + } + NSModule handle = NSLinkModule(image, libname.c_str(), + NSLINKMODULE_OPTION_BINDNOW | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(image); + return handle; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE); + return success; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* result = 0; + // Need to prepend symbols with '_' on Apple-gcc compilers + std::string rsym = '_' + sym; + + NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str()); + if (symbol) { + result = NSAddressOfSymbol(symbol); + } + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +} + +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> + +# include <stdio.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + DynamicLoader::LibraryHandle lh; + int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0); + wchar_t* wchars = new wchar_t[length + 1]; + wchars[0] = '\0'; + MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length); + lh = LoadLibraryW(wchars); + delete[] wchars; + return lh; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + return (int)FreeLibrary(lib); +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + void* result; +# if defined(__BORLANDC__) || defined(__WATCOMC__) + // Need to prepend symbols with '_' + std::string ssym = '_' + sym; + const char* rsym = ssym.c_str(); +# else + const char* rsym = sym.c_str(); +# endif + result = (void*)GetProcAddress(lib, rsym); +// Hack to cast pointer-to-data to pointer-to-function. +# ifdef __WATCOMC__ + return *(DynamicLoader::SymbolPointer*)(&result); +# else + return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); +# endif +} + +#elif defined(__BEOS__) +# include <be/kernel/image.h> +# include <be/support/Errors.h> + +static image_id last_dynamic_err = B_OK; + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + // image_id's are integers, errors are negative. Add one just in case we + // get a valid image_id of zero (is that even possible?). + image_id rc = load_add_on(libname.c_str()); + if (rc < 0) { + last_dynamic_err = rc; + return 0; + } + + return rc + 1; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (!lib) { + last_dynamic_err = B_BAD_VALUE; + return 0; + } else { + // The function dlclose() returns 0 on success, and non-zero on error. + status_t rc = unload_add_on(lib - 1); + if (rc != B_OK) { + last_dynamic_err = rc; + return 0; + } + } + + return 1; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + + result.psym = NULL; + + if (!lib) { + last_dynamic_err = B_BAD_VALUE; + } else { + // !!! FIXME: BeOS can do function-only lookups...does this ever + // !!! FIXME: actually _want_ a data symbol lookup, or was this union + // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only). + status_t rc = + get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid); + if (rc != B_OK) { + last_dynamic_err = rc; + result.psym = NULL; + } + } + return result.psym; +} + +#elif defined(__MINT__) +# define _GNU_SOURCE /* for program_invocation_name */ +# include <dld.h> +# include <errno.h> +# include <malloc.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + char* name = (char*)calloc(1, libname.size() + 1); + dld_init(program_invocation_name); + strncpy(name, libname.c_str(), libname.size()); + dld_link(libname.c_str()); + return (void*)name; +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + dld_unlink_by_file((char*)lib, 0); + free(lib); + return 0; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + result.pvoid = dld_get_symbol(sym.c_str()); + return result.psym; +} + +#else +# include <dlfcn.h> + +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( + const std::string& libname) +{ + return dlopen(libname.c_str(), RTLD_LAZY); +} + +int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) +{ + if (lib) { + // The function dlclose() returns 0 on success, and non-zero on error. + return !dlclose(lib); + } + // else + return 0; +} + +DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( + DynamicLoader::LibraryHandle lib, const std::string& sym) +{ + // Hack to cast pointer-to-data to pointer-to-function. + union + { + void* pvoid; + DynamicLoader::SymbolPointer psym; + } result; + result.pvoid = dlsym(lib, sym.c_str()); + return result.psym; +} + +#endif diff --git a/Tests/Plugin/src/example_exe.cxx b/Tests/Plugin/src/example_exe.cxx index 257a35c..fd810a9 100644 --- a/Tests/Plugin/src/example_exe.cxx +++ b/Tests/Plugin/src/example_exe.cxx @@ -1,4 +1,4 @@ -#include <kwsys/DynamicLoader.hxx> +#include "DynamicLoader.hxx" #include <example.h> @@ -24,20 +24,17 @@ extern "C" int example_exe_function() int main() { - std::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/"; - libName += kwsys::DynamicLoader::LibPrefix(); - libName += "example_mod_1"; - libName += kwsys::DynamicLoader::LibExtension(); - kwsys::DynamicLoader::LibraryHandle handle = - kwsys::DynamicLoader::OpenLibrary(libName.c_str()); + std::string const libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR + "/" EXAMPLE_EXE_MOD_PREFIX "example_mod_1" EXAMPLE_EXE_MOD_SUFFIX; + DynamicLoader::LibraryHandle handle = DynamicLoader::OpenLibrary(libName); if (!handle) { // Leave the .c_str() on this one. It is needed on OpenWatcom. std::cerr << "Could not open plugin \"" << libName.c_str() << "\"!" << std::endl; return 1; } - kwsys::DynamicLoader::SymbolPointer sym = - kwsys::DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function"); + DynamicLoader::SymbolPointer sym = + DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function"); if (!sym) { std::cerr << "Could not get plugin symbol \"example_mod_1_function\"!" << std::endl; @@ -52,6 +49,6 @@ int main() std::cerr << "Incorrect return value from plugin!" << std::endl; return 1; } - kwsys::DynamicLoader::CloseLibrary(handle); + DynamicLoader::CloseLibrary(handle); return 0; } diff --git a/Tests/Plugin/src/example_exe.h.in b/Tests/Plugin/src/example_exe.h.in index 62f0d9f..af71021 100644 --- a/Tests/Plugin/src/example_exe.h.in +++ b/Tests/Plugin/src/example_exe.h.in @@ -2,5 +2,7 @@ #define example_exe_h #define EXAMPLE_EXE_PLUGIN_DIR "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@" +#define EXAMPLE_EXE_MOD_PREFIX "@CMAKE_SHARED_MODULE_PREFIX@" +#define EXAMPLE_EXE_MOD_SUFFIX "@CMAKE_SHARED_MODULE_SUFFIX@" #endif diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 2a24421..52934f2 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -249,13 +249,13 @@ def check_target(c): if expected["backtrace"] is not None: expected_keys.append("backtrace") - assert actual["fragment"] == expected["fragment"] + assert matches(actual["fragment"], expected["fragment"]) assert actual["role"] == expected["role"] check_backtrace(obj, actual["backtrace"], expected["backtrace"]) assert sorted(actual.keys()) == sorted(expected_keys) - check_list_match(lambda a, e: is_string(a["fragment"], e["fragment"]), + check_list_match(lambda a, e: matches(a["fragment"], e["fragment"]), obj["link"]["commandFragments"], expected["link"]["commandFragments"], check=check_link_command_fragments, check_exception=lambda a, e: "Link fragment: %s" % a["fragment"], @@ -2218,6 +2218,42 @@ def gen_check_targets(c, g, inSource): }, ], }, + { + "fragment" : ".*TargetLinkDir\\\"?$", + "role" : "libraryPath", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 19, + "command": "target_link_directories", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, + { + "fragment" : ".*cxx_lib.*", + "role" : "libraries", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 6, + "command": "target_link_libraries", + "hasParent": True, + }, + { + "file" : "^cxx/CMakeLists\\.txt$", + "line": None, + "command": None, + "hasParent": False, + }, + ], + }, ], }, "archive": None, diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt index 17ff455..b0564f5 100644 --- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt +++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt @@ -16,3 +16,4 @@ target_link_libraries(cxx_static_exe PRIVATE cxx_static_lib) target_compile_options(cxx_exe PUBLIC TargetCompileOptions) target_link_options(cxx_exe PUBLIC TargetLinkOptions) +target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir") diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt new file mode 100644 index 0000000..503385f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at AppendLiteralQuotes.cmake:2 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "c" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake new file mode 100644 index 0000000..038fb3f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendLiteralQuotes.cmake @@ -0,0 +1,2 @@ +add_custom_command(OUTPUT a COMMAND b) +add_custom_command(OUTPUT a COMMAND "\"c\"" APPEND) diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt new file mode 100644 index 0000000..e7d6155 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at LiteralQuotes.cmake:1 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake new file mode 100644 index 0000000..046ddd9 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/LiteralQuotes.cmake @@ -0,0 +1 @@ +add_custom_command(OUTPUT a COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake index 20097b7..270df2f 100644 --- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake @@ -1,15 +1,18 @@ include(RunCMake) +run_cmake(AppendLiteralQuotes) run_cmake(AppendNoOutput) run_cmake(AppendNotOutput) run_cmake(BadArgument) run_cmake(GeneratedProperty) +run_cmake(LiteralQuotes) run_cmake(NoArguments) run_cmake(NoOutputOrTarget) run_cmake(OutputAndTarget) run_cmake(SourceByproducts) run_cmake(SourceUsesTerminal) run_cmake(TargetImported) +run_cmake(TargetLiteralQuotes) run_cmake(TargetNotInDir) if(${RunCMake_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt new file mode 100644 index 0000000..c4589b4 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at TargetLiteralQuotes.cmake:2 \(add_custom_command\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake new file mode 100644 index 0000000..5f11ed1 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/TargetLiteralQuotes.cmake @@ -0,0 +1,2 @@ +add_library(a) +add_custom_command(TARGET a POST_BUILD COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt b/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt b/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt new file mode 100644 index 0000000..bc5187a --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes-stderr.txt @@ -0,0 +1,7 @@ +CMake Error at LiteralQuotes.cmake:1 \(add_custom_target\): + COMMAND may not contain literal quotes: + + "b" + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake b/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake new file mode 100644 index 0000000..9870608 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/LiteralQuotes.cmake @@ -0,0 +1 @@ +add_custom_target(a COMMAND "\"b\"") diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake index d80ca19..49c7d3e 100644 --- a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake @@ -5,6 +5,7 @@ run_cmake(GeneratedProperty) run_cmake(NoArguments) run_cmake(BadTargetName) run_cmake(ByproductsNoCommand) +run_cmake(LiteralQuotes) run_cmake(UsesTerminalNoCommand) function(run_TargetOrder) @@ -307,7 +307,6 @@ CMAKE_CXX_SOURCES="\ cmExportFileGenerator \ cmExportInstallFileGenerator \ cmExportSet \ - cmExportSetMap \ cmExportTryCompileFileGenerator \ cmExprParserHelper \ cmExternalMakefileProjectGenerator \ |