diff options
Diffstat (limited to 'Source')
35 files changed, 1248 insertions, 267 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ea5c9be..96265d7 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 12) -set(CMake_VERSION_TWEAK 20131125) +set(CMake_VERSION_TWEAK 20131126) #set(CMake_VERSION_RC 1) diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 7fd4754..cb9e37e 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -237,7 +237,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) it != configs.end(); ++it) { std::vector<std::string> tlibs; - depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender); + if (depender->GetType() == cmTarget::INTERFACE_LIBRARY) + { + // For INTERFACE_LIBRARY depend on the interface instead. + depender->GetInterfaceLinkLibraries(it->c_str(), tlibs, depender); + } + else + { + depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender); + } // A target should not depend on itself. emitted.insert(depender->GetName()); for(std::vector<std::string>::const_iterator lib = tlibs.begin(); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 2ce4458..dc62284 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -388,14 +388,11 @@ void getCompatibleInterfaceProperties(cmTarget *target, if (!info) { - if (target->GetType() != cmTarget::INTERFACE_LIBRARY) - { - cmMakefile* mf = target->GetMakefile(); - cmOStringStream e; - e << "Exporting the target \"" << target->GetName() << "\" is not " - "allowed since its linker language cannot be determined"; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); - } + cmMakefile* mf = target->GetMakefile(); + cmOStringStream e; + e << "Exporting the target \"" << target->GetName() << "\" is not " + "allowed since its linker language cannot be determined"; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } @@ -447,15 +444,18 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX", ifaceProperties); - getCompatibleInterfaceProperties(target, ifaceProperties, 0); + if (target->GetType() != cmTarget::INTERFACE_LIBRARY) + { + getCompatibleInterfaceProperties(target, ifaceProperties, 0); - std::vector<std::string> configNames; - target->GetMakefile()->GetConfigurations(configNames); + std::vector<std::string> configNames; + target->GetMakefile()->GetConfigurations(configNames); - for (std::vector<std::string>::const_iterator ci = configNames.begin(); - ci != configNames.end(); ++ci) - { - getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str()); + for (std::vector<std::string>::const_iterator ci = configNames.begin(); + ci != configNames.end(); ++ci) + { + getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str()); + } } for (std::set<std::string>::const_iterator it = ifaceProperties.begin(); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 67972b9..17bf041 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -954,7 +954,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (!prop) { - if (target->IsImported()) + if (target->IsImported() + || target->GetType() == cmTarget::INTERFACE_LIBRARY) { return linkedTargetsContent; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 90cca1b..5a535c7 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -698,8 +698,8 @@ bool cmStrictTargetComparison::operator()(cmTarget *t1, cmTarget *t2) const int nameResult = strcmp(t1->GetName(), t2->GetName()); if (nameResult == 0) { - return strcmp(t1->GetMakefile()->GetStartDirectory(), - t2->GetMakefile()->GetStartDirectory()) < 0; + return strcmp(t1->GetMakefile()->GetStartOutputDirectory(), + t2->GetMakefile()->GetStartOutputDirectory()) < 0; } return nameResult < 0; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 20cd15e..e6f3d94 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1309,6 +1309,11 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() { cmTarget* t = &ti->second; + if (t->GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } + t->AppendBuildInterfaceIncludes(); for (std::vector<cmValueWithOrigin>::const_iterator it @@ -1461,6 +1466,10 @@ void cmGlobalGenerator::CheckLocalGenerators() for (cmTargets::iterator l = targets.begin(); l != targets.end(); l++) { + if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } const cmTarget::LinkLibraryVectorType& libs = l->second.GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin(); diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 3d939f3..f523a8f 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -327,6 +327,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( projectTargets.begin(); tt != projectTargets.end(); ++tt) { cmTarget* target = *tt; + if(target->GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); if(expath) { @@ -364,6 +368,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( projectTargets.begin(); tt != projectTargets.end(); ++tt) { cmTarget* target = *tt; + if(target->GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } bool written = false; // handle external vc project files diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 69b0a7a..e4ce13f 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -442,7 +442,8 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( { if(cmTarget* depTarget = this->FindTarget(0, ui->c_str())) { - if(depTarget->GetProperty("EXTERNAL_MSPROJECT")) + if(depTarget->GetType() != cmTarget::INTERFACE_LIBRARY + && depTarget->GetProperty("EXTERNAL_MSPROJECT")) { // This utility dependency names an external .vcproj target. // We use LinkLibraryDependencies="true" to link to it without diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 6ae8775..98ce685 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -47,7 +47,7 @@ cmLocalGenerator *cmGlobalWatcomWMakeGenerator::CreateLocalGenerator() lg->SetDefineWindowsNULL(true); lg->SetWindowsShell(true); lg->SetWatcomWMake(true); - lg->SetMakeSilentFlag("-s -h"); + lg->SetMakeSilentFlag("-s -h -e"); lg->SetGlobalGenerator(this); lg->SetIgnoreLibPrefix(true); lg->SetPassMakeflags(false); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index d309a2a..10578f2 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -645,7 +645,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // generators for them. bool createInstallGeneratorsForTargetFileSets = true; - if(target.IsFrameworkOnApple()) + if(target.IsFrameworkOnApple() + || target.GetType() == cmTarget::INTERFACE_LIBRARY) { createInstallGeneratorsForTargetFileSets = false; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index cf5798f..d26d6e9 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -541,6 +541,10 @@ void cmLocalGenerator::GenerateTargetManifest() t != targets.end(); ++t) { cmGeneratorTarget& target = *t->second; + if (target.Target->GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } if(configNames.empty()) { target.GenerateTargetManifest(0); @@ -2829,6 +2833,11 @@ cmLocalGenerator cmTargets& tgts = this->Makefile->GetTargets(); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l) { + if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } + // Include the user-specified pre-install script for this target. if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT")) { diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 5d2fb50..cd12c9d 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -70,7 +70,8 @@ void cmLocalNinjaGenerator::Generate() for(cmGeneratorTargetsType::iterator t = targets.begin(); t != targets.end(); ++t) { - if (t->second->Target->IsImported()) + if (t->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY + || t->second->Target->IsImported()) { continue; } @@ -327,16 +328,32 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( cmOStringStream cmd; for (std::vector<std::string>::const_iterator li = cmdLines.begin(); - li != cmdLines.end(); ++li) { - if (li != cmdLines.begin()) { - cmd << " && "; + li != cmdLines.end(); ++li) #ifdef _WIN32 - } else if (cmdLines.size() > 1) { - cmd << "cmd.exe /c "; -#endif + { + if (li != cmdLines.begin()) + { + cmd << " && "; + } + else if (cmdLines.size() > 1) + { + cmd << "cmd.exe /C \""; + } + cmd << *li; } + if (cmdLines.size() > 1) + { + cmd << "\""; + } +#else + { + if (li != cmdLines.begin()) + { + cmd << " && "; + } cmd << *li; - } + } +#endif return cmd.str(); } diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 9af5c29..5ada88d 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -151,7 +151,8 @@ void cmLocalUnixMakefileGenerator3::Generate() for(cmGeneratorTargetsType::iterator t = targets.begin(); t != targets.end(); ++t) { - if (t->second->Target->IsImported()) + if (t->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY + || t->second->Target->IsImported()) { continue; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 989aa5f..30a1557 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -868,6 +868,10 @@ void cmMakefile::ConfigureFinalPass() for (cmTargets::iterator l = this->Targets.begin(); l != this->Targets.end(); l++) { + if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } l->second.FinishConfigure(); } } @@ -2256,6 +2260,10 @@ void cmMakefile::ExpandVariablesCMP0019() l != this->Targets.end(); ++l) { cmTarget &t = l->second; + if (t.GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } includeDirs = t.GetProperty("INCLUDE_DIRECTORIES"); if(mightExpandVariablesCMP0019(includeDirs)) { diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 7b8a531..35818ee 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -25,9 +25,12 @@ cmMakefileLibraryTargetGenerator cmMakefileTargetGenerator(target->Target) { this->CustomCommandDriver = OnDepends; - this->Target->GetLibraryNames( - this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, - this->TargetNameImport, this->TargetNamePDB, this->ConfigName); + if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY) + { + this->Target->GetLibraryNames( + this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, + this->TargetNameImport, this->TargetNamePDB, this->ConfigName); + } this->OSXBundleGenerator = new cmOSXBundleGenerator(target, this->ConfigName); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f40532c..e3c058f 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -360,10 +360,11 @@ cmNinjaTargetGenerator cmMakefile* mf = this->GetMakefile(); - const bool usingMSVC = std::string("MSVC") == - (mf->GetDefinition("CMAKE_C_COMPILER_ID") ? - mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") : - mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID")); + const std::string cId = mf->GetDefinition("CMAKE_C_COMPILER_ID") + ? mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") + : mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"); + + const bool usingMSVC = (cId == "MSVC" || cId == "Intel"); // Tell ninja dependency format so all deps can be loaded into a database std::string deptype; diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 35717ce..a7d20ae 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -204,6 +204,11 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) "", makefile->GetCurrentOutputDirectory()); std::vector<std::string> depends; + if (const char *autogenDepends = + target->GetProperty("AUTOGEN_TARGET_DEPENDS")) + { + cmSystemTools::ExpandListArgument(autogenDepends, depends); + } std::vector<std::string> toolNames; if (target->GetPropertyAsBool("AUTOMOC")) { diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 1ccec68..7369fe6 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -428,6 +428,12 @@ struct cmStrCmp { return strcmp(input, m_test) == 0; } + // For use with binary_search + bool operator()(const char *str1, const char *str2) + { + return strcmp(str1, str2) < 0; + } + private: const char *m_test; }; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c05bb23..2423b27 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -255,32 +255,34 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->IsApple = this->Makefile->IsOn("APPLE"); // Setup default property values. - this->SetPropertyDefault("INSTALL_NAME_DIR", 0); - this->SetPropertyDefault("INSTALL_RPATH", ""); - this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF"); - this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF"); - this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF"); - this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); - this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); - this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); - this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); - this->SetPropertyDefault("Fortran_FORMAT", 0); - this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); - this->SetPropertyDefault("GNUtoMS", 0); - this->SetPropertyDefault("OSX_ARCHITECTURES", 0); - this->SetPropertyDefault("AUTOMOC", 0); - this->SetPropertyDefault("AUTOUIC", 0); - this->SetPropertyDefault("AUTORCC", 0); - this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); - this->SetPropertyDefault("AUTOUIC_OPTIONS", 0); - this->SetPropertyDefault("AUTORCC_OPTIONS", 0); - this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0); - this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); - this->SetPropertyDefault("WIN32_EXECUTABLE", 0); - this->SetPropertyDefault("MACOSX_BUNDLE", 0); - this->SetPropertyDefault("MACOSX_RPATH", 0); - this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); - + if (this->GetType() != INTERFACE_LIBRARY) + { + this->SetPropertyDefault("INSTALL_NAME_DIR", 0); + this->SetPropertyDefault("INSTALL_RPATH", ""); + this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF"); + this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF"); + this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF"); + this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("Fortran_FORMAT", 0); + this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); + this->SetPropertyDefault("GNUtoMS", 0); + this->SetPropertyDefault("OSX_ARCHITECTURES", 0); + this->SetPropertyDefault("AUTOMOC", 0); + this->SetPropertyDefault("AUTOUIC", 0); + this->SetPropertyDefault("AUTORCC", 0); + this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); + this->SetPropertyDefault("AUTOUIC_OPTIONS", 0); + this->SetPropertyDefault("AUTORCC_OPTIONS", 0); + this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0); + this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); + this->SetPropertyDefault("WIN32_EXECUTABLE", 0); + this->SetPropertyDefault("MACOSX_BUNDLE", 0); + this->SetPropertyDefault("MACOSX_RPATH", 0); + this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); + } // Collect the set of configuration types. std::vector<std::string> configNames; @@ -300,6 +302,11 @@ void cmTarget::SetMakefile(cmMakefile* mf) std::string configUpper = cmSystemTools::UpperCase(*ci); for(const char** p = configProps; *p; ++p) { + if (this->TargetTypeValue == INTERFACE_LIBRARY + && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0) + { + continue; + } std::string property = *p; property += configUpper; this->SetPropertyDefault(property.c_str(), 0); @@ -311,7 +318,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) // did not support this variable. Projects may still specify the // property directly. TODO: Make this depend on backwards // compatibility setting. - if(this->TargetTypeValue != cmTarget::EXECUTABLE) + if(this->TargetTypeValue != cmTarget::EXECUTABLE + && this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY) { std::string property = cmSystemTools::UpperCase(*ci); property += "_POSTFIX"; @@ -352,16 +360,22 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->InsertCompileOption(*it); } - this->SetPropertyDefault("C_VISIBILITY_PRESET", 0); - this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0); - this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0); + if (this->GetType() != INTERFACE_LIBRARY) + { + this->SetPropertyDefault("C_VISIBILITY_PRESET", 0); + this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0); + this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0); + } if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY || this->TargetTypeValue == cmTarget::MODULE_LIBRARY) { this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); } - this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); + if (this->GetType() != INTERFACE_LIBRARY) + { + this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); + } // Record current policies for later use. #define CAPTURE_TARGET_POLICY(POLICY) \ @@ -1373,12 +1387,63 @@ void cmTarget::GatherDependencies( const cmMakefile& mf, } //---------------------------------------------------------------------------- +static bool whiteListedInterfaceProperty(const char *prop) +{ + if(cmHasLiteralPrefix(prop, "INTERFACE_")) + { + return true; + } + static const char* builtIns[] = { + // ###: This must remain sorted. It is processed with a binary search. + "COMPATIBLE_INTERFACE_BOOL", + "COMPATIBLE_INTERFACE_NUMBER_MAX", + "COMPATIBLE_INTERFACE_NUMBER_MIN", + "COMPATIBLE_INTERFACE_STRING", + "EXCLUDE_FROM_ALL", + "EXCLUDE_FROM_DEFAULT_BUILD", + "EXPORT_NAME", + "IMPORTED_LINK_INTERFACE_LANGUAGES", + "IMPORTED", + "NAME", + "TYPE", + "VERSION" + }; + + if (std::binary_search(cmArrayBegin(builtIns), + cmArrayEnd(builtIns), + prop, + cmStrCmp(prop))) + { + return true; + } + + if (cmHasLiteralPrefix(prop, "EXCLUDE_FROM_DEFAULT_BUILD_") + || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LANGUAGES_") + || cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) + { + return true; + } + + return false; +} + +//---------------------------------------------------------------------------- void cmTarget::SetProperty(const char* prop, const char* value) { if (!prop) { return; } + if (this->GetType() == INTERFACE_LIBRARY + && !whiteListedInterfaceProperty(prop)) + { + cmOStringStream e; + e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " + "The property \"" << prop << "\" is not allowed."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + if (strcmp(prop, "NAME") == 0) { cmOStringStream e; @@ -1448,6 +1513,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value, { return; } + if (this->GetType() == INTERFACE_LIBRARY + && !whiteListedInterfaceProperty(prop)) + { + cmOStringStream e; + e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " + "The property \"" << prop << "\" is not allowed."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } if (strcmp(prop, "NAME") == 0) { cmOStringStream e; @@ -2563,6 +2637,16 @@ const char *cmTarget::GetProperty(const char* prop, return 0; } + if (this->GetType() == INTERFACE_LIBRARY + && !whiteListedInterfaceProperty(prop)) + { + cmOStringStream e; + e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " + "The property \"" << prop << "\" is not allowed."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return 0; + } + if (strcmp(prop, "NAME") == 0) { return this->GetName(); @@ -4436,7 +4520,8 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p, bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, const char *config) const { - if (this->TargetTypeValue == OBJECT_LIBRARY) + if (this->TargetTypeValue == OBJECT_LIBRARY + || this->TargetTypeValue == INTERFACE_LIBRARY) { return false; } @@ -4449,7 +4534,8 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, const char *config) const { - if (this->TargetTypeValue == OBJECT_LIBRARY) + if (this->TargetTypeValue == OBJECT_LIBRARY + || this->TargetTypeValue == INTERFACE_LIBRARY) { return false; } @@ -4461,7 +4547,8 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, const char *config) const { - if (this->TargetTypeValue == OBJECT_LIBRARY) + if (this->TargetTypeValue == OBJECT_LIBRARY + || this->TargetTypeValue == INTERFACE_LIBRARY) { return false; } @@ -4473,7 +4560,8 @@ bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, const char *config) const { - if (this->TargetTypeValue == OBJECT_LIBRARY) + if (this->TargetTypeValue == OBJECT_LIBRARY + || this->TargetTypeValue == INTERFACE_LIBRARY) { return false; } @@ -5108,34 +5196,37 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, { emitted.insert(*li); } - LinkImplementation const* impl = this->GetLinkImplementation(config, - headTarget); - for(std::vector<std::string>::const_iterator - li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) + if (this->GetType() != cmTarget::INTERFACE_LIBRARY) { - if(emitted.insert(*li).second) + LinkImplementation const* impl = this->GetLinkImplementation(config, + headTarget); + for(std::vector<std::string>::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { - if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str())) + if(emitted.insert(*li).second) { - // This is a runtime dependency on another shared library. - if(tgt->GetType() == cmTarget::SHARED_LIBRARY) + if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str())) { - iface.SharedDeps.push_back(*li); + // This is a runtime dependency on another shared library. + if(tgt->GetType() == cmTarget::SHARED_LIBRARY) + { + iface.SharedDeps.push_back(*li); + } + } + else + { + // TODO: Recognize shared library file names. Perhaps this + // should be moved to cmComputeLinkInformation, but that creates + // a chicken-and-egg problem since this list is needed for its + // construction. } - } - else - { - // TODO: Recognize shared library file names. Perhaps this - // should be moved to cmComputeLinkInformation, but that creates - // a chicken-and-egg problem since this list is needed for its - // construction. } } - } - if(this->LinkLanguagePropagatesToDependents()) - { - // Targets using this archive need its language runtime libraries. - iface.Languages = impl->Languages; + if(this->LinkLanguagePropagatesToDependents()) + { + // Targets using this archive need its language runtime libraries. + iface.Languages = impl->Languages; + } } } } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 635d8cb..10663b7 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -184,7 +184,8 @@ void cmVisualStudio10TargetGenerator::WriteString(const char* line, void cmVisualStudio10TargetGenerator::Generate() { // do not generate external ms projects - if(this->Target->GetProperty("EXTERNAL_MSPROJECT")) + if(this->Target->GetType() == cmTarget::INTERFACE_LIBRARY + || this->Target->GetProperty("EXTERNAL_MSPROJECT")) { return; } diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index a9d89d4..3745f78 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -115,6 +115,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_USE_Base64 1) SET(KWSYS_USE_Directory 1) SET(KWSYS_USE_DynamicLoader 1) + SET(KWSYS_USE_Encoding 1) SET(KWSYS_USE_Glob 1) SET(KWSYS_USE_MD5 1) SET(KWSYS_USE_Process 1) @@ -125,6 +126,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_USE_FundamentalType 1) SET(KWSYS_USE_Terminal 1) SET(KWSYS_USE_IOStream 1) + SET(KWSYS_USE_FStream 1) SET(KWSYS_USE_String 1) SET(KWSYS_USE_SystemInformation 1) SET(KWSYS_USE_CPU 1) @@ -133,18 +135,32 @@ ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # Enforce component dependencies. IF(KWSYS_USE_SystemTools) SET(KWSYS_USE_Directory 1) + SET(KWSYS_USE_FStream 1) + SET(KWSYS_USE_Encoding 1) ENDIF(KWSYS_USE_SystemTools) IF(KWSYS_USE_Glob) SET(KWSYS_USE_Directory 1) SET(KWSYS_USE_SystemTools 1) SET(KWSYS_USE_RegularExpression 1) + SET(KWSYS_USE_FStream 1) + SET(KWSYS_USE_Encoding 1) ENDIF(KWSYS_USE_Glob) IF(KWSYS_USE_Process) SET(KWSYS_USE_System 1) + SET(KWSYS_USE_Encoding 1) ENDIF(KWSYS_USE_Process) IF(KWSYS_USE_SystemInformation) SET(KWSYS_USE_Process 1) ENDIF(KWSYS_USE_SystemInformation) +IF(KWSYS_USE_System) + SET(KWSYS_USE_Encoding 1) +ENDIF(KWSYS_USE_System) +IF(KWSYS_USE_Directory) + SET(KWSYS_USE_Encoding 1) +ENDIF(KWSYS_USE_Directory) +IF(KWSYS_USE_FStream) + SET(KWSYS_USE_Encoding 1) +ENDIF(KWSYS_USE_FStream) # Setup the large file support default. IF(KWSYS_LFS_DISABLE) @@ -153,6 +169,11 @@ ELSE(KWSYS_LFS_DISABLE) SET(KWSYS_LFS_REQUESTED 1) ENDIF(KWSYS_LFS_DISABLE) +# Specify default 8 bit encoding for Windows +IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) + SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP) +ENDIF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) + # Enable testing if building standalone. IF(KWSYS_STANDALONE) INCLUDE(Dart) @@ -509,6 +530,12 @@ IF(KWSYS_USE_FundamentalType) "Checking whether char is signed" DIRECT) ENDIF(KWSYS_USE_FundamentalType) +IF(KWSYS_USE_Encoding) + # Look for type size helper macros. + KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING + "Checking whether wstring is available" DIRECT) +ENDIF(KWSYS_USE_Encoding) + IF(KWSYS_USE_IOStream) # Determine whether iostreams support long long. SET(KWSYS_PLATFORM_CXX_TEST_DEFINES @@ -864,8 +891,8 @@ SET(KWSYS_HXX_FILES Configure String # Add selected C++ classes. SET(cppclasses - Directory DynamicLoader Glob RegularExpression SystemTools - CommandLineArguments IOStream SystemInformation + Directory DynamicLoader Encoding Glob RegularExpression SystemTools + CommandLineArguments IOStream FStream SystemInformation ) FOREACH(cpp ${cppclasses}) IF(KWSYS_USE_${cpp}) @@ -881,7 +908,7 @@ ENDFOREACH(cpp) # Add selected C components. FOREACH(c - Process Base64 FundamentalType MD5 Terminal System String CPU + Process Base64 Encoding FundamentalType MD5 Terminal System String CPU ) IF(KWSYS_USE_${c}) # Use the corresponding header file. @@ -912,16 +939,24 @@ IF(KWSYS_USE_Process) ENDIF(KWSYS_USE_Process) # Add selected C sources. -FOREACH(c Base64 MD5 Terminal System String) +FOREACH(c Base64 Encoding MD5 Terminal System String) IF(KWSYS_USE_${c}) - SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${c}.c) + IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c) + LIST(APPEND KWSYS_C_SRCS ${c}C.c) + ELSE() + LIST(APPEND KWSYS_C_SRCS ${c}.c) + ENDIF() ENDIF(KWSYS_USE_${c}) ENDFOREACH(c) # Configure headers of C++ classes and construct the list of sources. FOREACH(c ${KWSYS_CLASSES}) # Add this source to the list of source files for the library. - SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${c}.cxx) + IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx) + LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx) + ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx) + LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx) + ENDIF() # Configure the header for this class. CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx @@ -1047,6 +1082,12 @@ IF(KWSYS_USE_String) COMPILE_FLAGS "-DKWSYS_STRING_C") ENDIF(KWSYS_USE_String) +IF(KWSYS_USE_Encoding) + # Set default 8 bit encoding in "EndcodingC.c". + SET_PROPERTY(SOURCE EncodingC.c APPEND PROPERTY COMPILE_DEFINITIONS + KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE}) +ENDIF(KWSYS_USE_Encoding) + #----------------------------------------------------------------------------- # Setup testing if not being built as part of another project. IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) @@ -1090,6 +1131,11 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) testCommandLineArguments testCommandLineArguments1 ) + IF(KWSYS_STL_HAS_WSTRING) + SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} + testEncoding + ) + ENDIF(KWSYS_STL_HAS_WSTRING) IF(KWSYS_USE_SystemInformation) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation) ENDIF(KWSYS_USE_SystemInformation) diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in index 716b84f..8f5ace2 100644 --- a/Source/kwsys/Configure.hxx.in +++ b/Source/kwsys/Configure.hxx.in @@ -36,6 +36,9 @@ /* Whether STL is in std namespace. */ #define @KWSYS_NAMESPACE@_STL_HAVE_STD @KWSYS_STL_HAVE_STD@ +/* Whether wstring is available. */ +#define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@ + /* Whether the STL string has operator<< for ostream. */ #define @KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM @KWSYS_STL_STRING_HAVE_OSTREAM@ @@ -170,6 +173,7 @@ # define KWSYS_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE # define KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE # define KWSYS_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS +# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING #endif #endif diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index b884747..d54e607 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -14,6 +14,8 @@ #include KWSYS_HEADER(Configure.hxx) +#include KWSYS_HEADER(Encoding.hxx) + #include KWSYS_HEADER(stl/string) #include KWSYS_HEADER(stl/vector) @@ -22,6 +24,7 @@ #if 0 # include "Directory.hxx.in" # include "Configure.hxx.in" +# include "Encoding.hxx.in" # include "kwsys_stl.hxx.in" # include "kwsys_stl_string.hxx.in" # include "kwsys_stl_vector.hxx.in" @@ -120,10 +123,10 @@ bool Directory::Load(const char* name) buf = new char[n + 2 + 1]; sprintf(buf, "%s/*", name); } - struct _finddata_t data; // data of current file + struct _wfinddata_t data; // data of current file // Now put them into the file array - srchHandle = _findfirst(buf, &data); + srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data); delete [] buf; if ( srchHandle == -1 ) @@ -134,9 +137,9 @@ bool Directory::Load(const char* name) // Loop through names do { - this->Internal->Files.push_back(data.name); + this->Internal->Files.push_back(Encoding::ToNarrow(data.name)); } - while ( _findnext(srchHandle, &data) != -1 ); + while ( _wfindnext(srchHandle, &data) != -1 ); this->Internal->Path = name; return _findclose(srchHandle) != -1; } @@ -160,10 +163,10 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name) buf = new char[n + 2 + 1]; sprintf(buf, "%s/*", name); } - struct _finddata_t data; // data of current file + struct _wfinddata_t data; // data of current file // Now put them into the file array - srchHandle = _findfirst(buf, &data); + srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data); delete [] buf; if ( srchHandle == -1 ) @@ -177,7 +180,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name) { count++; } - while ( _findnext(srchHandle, &data) != -1 ); + while ( _wfindnext(srchHandle, &data) != -1 ); _findclose(srchHandle); return count; } diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index fd83752..44cf6af 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -186,13 +186,12 @@ namespace KWSYS_NAMESPACE DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname) { DynamicLoader::LibraryHandle lh; -#ifdef UNICODE - wchar_t libn[MB_CUR_MAX]; - mbstowcs(libn, libname, MB_CUR_MAX); - lh = LoadLibrary(libn); -#else - lh = LoadLibrary(libname); -#endif + int length = MultiByteToWideChar(CP_UTF8, 0, libname, -1, NULL, 0); + wchar_t* wchars = new wchar_t[length+1]; + wchars[0] = '\0'; + MultiByteToWideChar(CP_UTF8, 0, libname, -1, wchars, length); + lh = LoadLibraryW(wchars); + delete [] wchars; return lh; } @@ -238,13 +237,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( #else const char *rsym = sym; #endif -#ifdef UNICODE - wchar_t wsym[MB_CUR_MAX]; - mbstowcs(wsym, rsym, MB_CUR_MAX); - result = GetProcAddress(lib, wsym); -#else result = (void*)GetProcAddress(lib, rsym); -#endif #if defined(__BORLANDC__) || defined(__WATCOMC__) delete[] rsym; #endif diff --git a/Source/kwsys/Encoding.h.in b/Source/kwsys/Encoding.h.in new file mode 100644 index 0000000..591c5a8 --- /dev/null +++ b/Source/kwsys/Encoding.h.in @@ -0,0 +1,79 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef @KWSYS_NAMESPACE@_Encoding_h +#define @KWSYS_NAMESPACE@_Encoding_h + +#include <@KWSYS_NAMESPACE@/Configure.h> +#include <wchar.h> + +/* Redefine all public interface symbol names to be in the proper + namespace. These macros are used internally to kwsys only, and are + not visible to user code. Use kwsysHeaderDump.pl to reproduce + these macros after making changes to the interface. */ +#if !defined(KWSYS_NAMESPACE) +# define kwsys_ns(x) @KWSYS_NAMESPACE@##x +# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT +#endif +#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define kwsysEncoding kwsys_ns(Encoding) +# define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs) +# define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide) +# define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs) +# define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow) +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +/* Convert a narrow string to a wide string. + On Windows, UTF-8 is assumed, and on other platforms, + the current locale is assumed. + */ +kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src, size_t n); + +/* Convert a narrow string to a wide string. + This can return NULL if the conversion fails. */ +kwsysEXPORT wchar_t* kwsysEncoding_DupToWide(const char* src); + + +/* Convert a wide string to a narrow string. + On Windows, UTF-8 is assumed, and on other platforms, + the current locale is assumed. */ +kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src, size_t n); + +/* Convert a wide string to a narrow string. + This can return NULL if the conversion fails. */ +kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str); + + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +/* If we are building a kwsys .c or .cxx file, let it use these macros. + Otherwise, undefine them to keep the namespace clean. */ +#if !defined(KWSYS_NAMESPACE) +# undef kwsys_ns +# undef kwsysEXPORT +# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# undef kwsysEncoding +# undef kwsysEncoding_mbstowcs +# undef kwsysEncoding_DupToWide +# undef kwsysEncoding_wcstombs +# undef kwsysEncoding_DupToNarrow +# endif +#endif + +#endif diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in new file mode 100644 index 0000000..60a4a8e --- /dev/null +++ b/Source/kwsys/Encoding.hxx.in @@ -0,0 +1,56 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef @KWSYS_NAMESPACE@_Encoding_hxx +#define @KWSYS_NAMESPACE@_Encoding_hxx + +#include <@KWSYS_NAMESPACE@/Configure.hxx> +#include <@KWSYS_NAMESPACE@/stl/string> + +/* Define these macros temporarily to keep the code readable. */ +#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define kwsys_stl @KWSYS_NAMESPACE@_stl +#endif + +namespace @KWSYS_NAMESPACE@ +{ +class @KWSYS_NAMESPACE@_EXPORT Encoding +{ +public: + /** + * Convert between char and wchar_t + */ + +#if @KWSYS_NAMESPACE@_STL_HAS_WSTRING + + // Convert a narrow string to a wide string. + // On Windows, UTF-8 is assumed, and on other platforms, + // the current locale is assumed. + static kwsys_stl::wstring ToWide(const kwsys_stl::string& str); + static kwsys_stl::wstring ToWide(const char* str); + + // Convert a wide string to a narrow string. + // On Windows, UTF-8 is assumed, and on other platforms, + // the current locale is assumed. + static kwsys_stl::string ToNarrow(const kwsys_stl::wstring& str); + static kwsys_stl::string ToNarrow(const wchar_t* str); + +#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING + +}; // class Encoding +} // namespace @KWSYS_NAMESPACE@ + +/* Undefine temporary macros. */ +#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# undef kwsys_stl +#endif + +#endif diff --git a/Source/kwsys/EncodingC.c b/Source/kwsys/EncodingC.c new file mode 100644 index 0000000..a36eecc --- /dev/null +++ b/Source/kwsys/EncodingC.c @@ -0,0 +1,79 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(Encoding.h) + +/* Work-around CMake dependency scanning limitation. This must + duplicate the above list of headers. */ +#if 0 +# include "Encoding.h.in" +#endif + +#include <stdlib.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* str, size_t n) +{ + if(str == 0) + { + return (size_t)-1; + } +#ifdef _WIN32 + return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, + str, -1, dest, (int)n) - 1; +#else + return mbstowcs(dest, str, n); +#endif +} + +wchar_t* kwsysEncoding_DupToWide(const char* str) +{ + wchar_t* ret = NULL; + size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1; + if(length > 0) + { + ret = malloc((length)*sizeof(wchar_t)); + ret[0] = 0; + kwsysEncoding_mbstowcs(ret, str, length); + } + return ret; +} + +size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* str, size_t n) +{ + if(str == 0) + { + return (size_t)-1; + } +#ifdef _WIN32 + return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1, + dest, (int)n, NULL, NULL) - 1; +#else + return wcstombs(dest, str, n); +#endif +} + +char* kwsysEncoding_DupToNarrow(const wchar_t* str) +{ + char* ret = NULL; + size_t length = kwsysEncoding_wcstombs(0, str, 0); + if(length > 0) + { + ret = malloc(length); + ret[0] = 0; + kwsysEncoding_wcstombs(ret, str, length); + } + return ret; +} diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx new file mode 100644 index 0000000..aebc148 --- /dev/null +++ b/Source/kwsys/EncodingCXX.cxx @@ -0,0 +1,88 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifdef __osf__ +# define _OSF_SOURCE +# define _POSIX_C_SOURCE 199506L +# define _XOPEN_SOURCE_EXTENDED +#endif + +#include "kwsysPrivate.h" +#include KWSYS_HEADER(Encoding.hxx) +#include KWSYS_HEADER(Encoding.h) +#include KWSYS_HEADER(stl/vector) + +// Work-around CMake dependency scanning limitation. This must +// duplicate the above list of headers. +#if 0 +# include "Encoding.hxx.in" +# include "Encoding.h.in" +#endif + +#include <stdlib.h> + +#ifdef _MSC_VER +# pragma warning (disable: 4786) +#endif + +// Windows API. +#if defined(_WIN32) +# include <windows.h> +#endif + +namespace KWSYS_NAMESPACE +{ + +#if KWSYS_STL_HAS_WSTRING + +kwsys_stl::wstring Encoding::ToWide(const kwsys_stl::string& str) +{ + return ToWide(str.c_str()); +} + +kwsys_stl::string Encoding::ToNarrow(const kwsys_stl::wstring& str) +{ + return ToNarrow(str.c_str()); +} + +kwsys_stl::wstring Encoding::ToWide(const char* cstr) +{ + kwsys_stl::wstring wstr; + size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1; + if(length > 0) + { + kwsys_stl::vector<wchar_t> wchars(length); + if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) + { + wstr = &wchars[0]; + } + } + return wstr; +} + +kwsys_stl::string Encoding::ToNarrow(const wchar_t* wcstr) +{ + kwsys_stl::string str; + size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1; + if(length > 0) + { + std::vector<char> chars(length); + if(kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) + { + str = &chars[0]; + } + } + return str; +} +#endif // KWSYS_STL_HAS_WSTRING + +} // namespace KWSYS_NAMESPACE diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in new file mode 100644 index 0000000..8170fb3 --- /dev/null +++ b/Source/kwsys/FStream.hxx.in @@ -0,0 +1,172 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef @KWSYS_NAMESPACE@_FStream_hxx +#define @KWSYS_NAMESPACE@_FStream_hxx + +#include <@KWSYS_NAMESPACE@/ios/fstream> +#include <@KWSYS_NAMESPACE@/Encoding.hxx> + +namespace @KWSYS_NAMESPACE@ +{ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + template<typename CharType,typename Traits> + class basic_filebuf : public std::basic_filebuf<CharType,Traits> + { + public: + typedef std::basic_filebuf<CharType,Traits> my_base_type; + basic_filebuf *open(char const *s,std::ios_base::openmode mode) + { + my_base_type::open(Encoding::ToWide(s).c_str(), mode); + return this; + } + }; + + template<typename CharType,typename Traits = std::char_traits<CharType> > + class basic_ifstream : public std::basic_istream<CharType,Traits> + { + public: + typedef basic_filebuf<CharType,Traits> internal_buffer_type; + typedef std::basic_istream<CharType,Traits> internal_stream_type; + + basic_ifstream() : internal_stream_type(new internal_buffer_type()) + { + buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()); + } + explicit basic_ifstream(char const *file_name, + std::ios_base::openmode mode = std::ios_base::in) + : internal_stream_type(new internal_buffer_type()) + { + buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()); + open(file_name,mode); + } + void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) + { + if(!buf_->open(file_name,mode | std::ios_base::in)) + { + this->setstate(std::ios_base::failbit); + } + else + { + this->clear(); + } + } + bool is_open() + { + return buf_->is_open(); + } + bool is_open() const + { + return buf_->is_open(); + } + void close() + { + if(!buf_->close()) + { + this->setstate(std::ios_base::failbit); + } + else + { + this->clear(); + } + } + + internal_buffer_type *rdbuf() const + { + return buf_.get(); + } + + ~basic_ifstream() + { + buf_->close(); + delete buf_; + } + + private: + internal_buffer_type* buf_; +}; + +template<typename CharType,typename Traits = std::char_traits<CharType> > +class basic_ofstream : public std::basic_ostream<CharType,Traits> +{ + public: + typedef basic_filebuf<CharType,Traits> internal_buffer_type; + typedef std::basic_ostream<CharType,Traits> internal_stream_type; + + basic_ofstream() : internal_stream_type(new internal_buffer_type()) + { + buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()); + } + explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) : + internal_stream_type(new internal_buffer_type()) + { + buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()); + open(file_name,mode); + } + void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) + { + if(!buf_->open(file_name,mode | std::ios_base::out)) + { + this->setstate(std::ios_base::failbit); + } + else + { + this->clear(); + } + } + bool is_open() + { + return buf_->is_open(); + } + bool is_open() const + { + return buf_->is_open(); + } + void close() + { + if(!buf_->close()) + { + this->setstate(std::ios_base::failbit); + } + else + { + this->clear(); + } + } + + internal_buffer_type *rdbuf() const + { + return buf_.get(); + } + ~basic_ofstream() + { + buf_->close(); + delete buf_; + } + + private: + internal_buffer_type* buf_; +}; + + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + +#else + using @KWSYS_NAMESPACE@_ios_namespace::basic_filebuf; + using @KWSYS_NAMESPACE@_ios_namespace::ofstream; + using @KWSYS_NAMESPACE@_ios_namespace::ifstream; +#endif + +} + + + +#endif diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index c836f9b..c8ec754 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -12,12 +12,14 @@ #include "kwsysPrivate.h" #include KWSYS_HEADER(Process.h) #include KWSYS_HEADER(System.h) +#include KWSYS_HEADER(Encoding.h) /* Work-around CMake dependency scanning limitation. This must duplicate the above list of headers. */ #if 0 # include "Process.h.in" # include "System.h.in" +# include "Encoding_c.h.in" #endif /* @@ -88,9 +90,10 @@ typedef LARGE_INTEGER kwsysProcessTime; typedef struct kwsysProcessCreateInformation_s { /* Windows child startup control data. */ - STARTUPINFO StartupInfo; + STARTUPINFOW StartupInfo; } kwsysProcessCreateInformation; + /*--------------------------------------------------------------------------*/ typedef struct kwsysProcessPipeData_s kwsysProcessPipeData; static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd); @@ -197,14 +200,14 @@ struct kwsysProcess_s int State; /* The command lines to execute. */ - char** Commands; + wchar_t** Commands; int NumberOfCommands; /* The exit code of each command. */ DWORD* CommandExitCodes; /* The working directory for the child process. */ - char* WorkingDirectory; + wchar_t* WorkingDirectory; /* Whether to create the child as a detached process. */ int OptionDetach; @@ -299,7 +302,7 @@ struct kwsysProcess_s /* Real working directory of our own process. */ DWORD RealWorkingDirectoryLength; - char* RealWorkingDirectory; + wchar_t* RealWorkingDirectory; }; /*--------------------------------------------------------------------------*/ @@ -546,7 +549,7 @@ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) { int newNumberOfCommands; - char** newCommands; + wchar_t** newCommands; /* Make sure we have a command to add. */ if(!cp || !command || !*command) @@ -554,9 +557,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) return 0; } + /* Allocate a new array for command pointers. */ newNumberOfCommands = cp->NumberOfCommands + 1; - if(!(newCommands = (char**)malloc(sizeof(char*) * newNumberOfCommands))) + if(!(newCommands = (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands))) { /* Out of memory. */ return 0; @@ -585,8 +589,8 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) /* Allocate enough space for the command. We do not need an extra byte for the terminating null because we allocated a space for the first argument that we will not use. */ - newCommands[cp->NumberOfCommands] = (char*)malloc(length); - if(!newCommands[cp->NumberOfCommands]) + char* new_cmd = malloc(length); + if(!new_cmd) { /* Out of memory. */ free(newCommands); @@ -595,9 +599,13 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) /* Construct the command line in the allocated buffer. */ kwsysProcessComputeCommandLine(cp, command, - newCommands[cp->NumberOfCommands]); + new_cmd); + + newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(new_cmd); + free(new_cmd); } + /* Save the new array of commands. */ free(cp->Commands); cp->Commands = newCommands; @@ -633,22 +641,26 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) } if(dir && dir[0]) { + wchar_t* wdir = kwsysEncoding_DupToWide(dir); /* We must convert the working directory to a full path. */ - DWORD length = GetFullPathName(dir, 0, 0, 0); + DWORD length = GetFullPathNameW(wdir, 0, 0, 0); if(length > 0) { - cp->WorkingDirectory = (char*)malloc(length); - if(!cp->WorkingDirectory) + wchar_t* work_dir = malloc(length*sizeof(wchar_t)); + if(!work_dir) { + free(wdir); return 0; } - if(!GetFullPathName(dir, length, cp->WorkingDirectory, 0)) + if(!GetFullPathNameW(wdir, length, work_dir, 0)) { - free(cp->WorkingDirectory); - cp->WorkingDirectory = 0; + free(work_dir); + free(wdir); return 0; } + cp->WorkingDirectory = work_dir; } + free(wdir); } return 1; } @@ -879,13 +891,13 @@ void kwsysProcess_Execute(kwsysProcess* cp) to make pipe file paths evaluate correctly. */ if(cp->WorkingDirectory) { - if(!GetCurrentDirectory(cp->RealWorkingDirectoryLength, + if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength, cp->RealWorkingDirectory)) { kwsysProcessCleanup(cp, 1); return; } - SetCurrentDirectory(cp->WorkingDirectory); + SetCurrentDirectoryW(cp->WorkingDirectory); } /* Initialize startup info data. */ @@ -1003,7 +1015,7 @@ void kwsysProcess_Execute(kwsysProcess* cp) /* Restore the working directory. */ if(cp->RealWorkingDirectory) { - SetCurrentDirectory(cp->RealWorkingDirectory); + SetCurrentDirectoryW(cp->RealWorkingDirectory); free(cp->RealWorkingDirectory); cp->RealWorkingDirectory = 0; } @@ -1507,10 +1519,10 @@ int kwsysProcessInitialize(kwsysProcess* cp) /* Allocate space to save the real working directory of this process. */ if(cp->WorkingDirectory) { - cp->RealWorkingDirectoryLength = GetCurrentDirectory(0, 0); + cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0); if(cp->RealWorkingDirectoryLength > 0) { - cp->RealWorkingDirectory = (char*)malloc(cp->RealWorkingDirectoryLength); + cp->RealWorkingDirectory = malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t)); if(!cp->RealWorkingDirectory) { return 0; @@ -1547,9 +1559,11 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, else if(cp->PipeFileSTDIN) { /* Create a handle to read a file for stdin. */ - HANDLE fin = CreateFile(cp->PipeFileSTDIN, GENERIC_READ|GENERIC_WRITE, + wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); + HANDLE fin = CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + free(wstdin); if(fin == INVALID_HANDLE_VALUE) { return 0; @@ -1655,7 +1669,7 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, /* Create the child in a suspended state so we can wait until all children have been created before running any one. */ - if(!CreateProcess(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0, + if(!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si->StartupInfo, &cp->ProcessInformation[index])) { return 0; @@ -1729,6 +1743,7 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event) int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) { HANDLE fout; + wchar_t* wname; if(!name) { return 1; @@ -1738,8 +1753,10 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) kwsysProcessCleanupHandle(phandle); /* Create a handle to write a file for the pipe. */ - fout = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, 0, + wname = kwsysEncoding_DupToWide(name); + fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); + free(wname); if(fout == INVALID_HANDLE_VALUE) { return 0; @@ -1883,10 +1900,13 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error) { /* Format the error message. */ DWORD original = GetLastError(); - DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE]; + DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, original, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE, 0); + err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0); + WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage, + KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL); if(length < 1) { /* FormatMessage failed. Use a default message. */ @@ -1924,7 +1944,7 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error) /* Restore the working directory. */ if(cp->RealWorkingDirectory) { - SetCurrentDirectory(cp->RealWorkingDirectory); + SetCurrentDirectoryW(cp->RealWorkingDirectory); } } @@ -2222,7 +2242,7 @@ static void kwsysProcessSetExitException(kwsysProcess* cp, int code) case STATUS_NO_MEMORY: default: cp->ExitException = kwsysProcess_Exception_Other; - sprintf(cp->ExitExceptionString, "Exit code 0x%x\n", code); + _snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code); break; } } @@ -2430,7 +2450,7 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self) loaded in this program. This does not actually increment the reference count to the module so we do not need to close the handle. */ - HMODULE hNT = GetModuleHandle("ntdll.dll"); + HMODULE hNT = GetModuleHandleW(L"ntdll.dll"); if(hNT) { /* Get pointers to the needed API functions. */ @@ -2534,7 +2554,7 @@ static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self) loaded in this program. This does not actually increment the reference count to the module so we do not need to close the handle. */ - HMODULE hKernel = GetModuleHandle("kernel32.dll"); + HMODULE hKernel = GetModuleHandleW(L"kernel32.dll"); if(hKernel) { self->P_CreateToolhelp32Snapshot = diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 2672730..2f6c949 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -253,7 +253,7 @@ static bool call_cpuid(int select, int result[4]) _asm { #ifdef CPUID_AWARE_COMPILER ; we must push/pop the registers <<CPUID>> writes to, as the - ; optimiser doesn't know about <<CPUID>>, and so doesn't expect + ; optimiser does not know about <<CPUID>>, and so does not expect ; these registers to change. push eax push ebx @@ -2454,8 +2454,8 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() if (!retrieved) { HKEY hKey = NULL; - LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, + LONG err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey); if (ERROR_SUCCESS == err) @@ -2464,7 +2464,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() DWORD data = 0; DWORD dwSize = sizeof(DWORD); - err = RegQueryValueEx(hKey, "~MHz", 0, + err = RegQueryValueExW(hKey, L"~MHz", 0, &dwType, (LPBYTE) &data, &dwSize); if (ERROR_SUCCESS == err) @@ -5017,19 +5017,19 @@ bool SystemInformationImplementation::QueryOSInformation() this->OSName = "Windows"; - OSVERSIONINFOEX osvi; + OSVERSIONINFOEXW osvi; BOOL bIsWindows64Bit; BOOL bOsVersionInfoEx; char operatingSystem[256]; // Try calling GetVersionEx using the OSVERSIONINFOEX structure. - ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); - bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi); + ZeroMemory (&osvi, sizeof (OSVERSIONINFOEXW)); + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW); + bOsVersionInfoEx = GetVersionExW ((OSVERSIONINFOW*)&osvi); if (!bOsVersionInfoEx) { - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - if (!GetVersionEx ((OSVERSIONINFO *) &osvi)) + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOW); + if (!GetVersionExW((OSVERSIONINFOW*)&osvi)) { return false; } @@ -5115,19 +5115,19 @@ bool SystemInformationImplementation::QueryOSInformation() #endif // VER_NT_WORKSTATION { HKEY hKey; - char szProductType[80]; + wchar_t szProductType[80]; DWORD dwBufLen; // Query the registry to retrieve information. - RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); - RegQueryValueEx (hKey, "ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen); + RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); + RegQueryValueExW(hKey, L"ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen); RegCloseKey (hKey); - if (lstrcmpi ("WINNT", szProductType) == 0) + if (lstrcmpiW(L"WINNT", szProductType) == 0) { this->OSRelease += " Professional"; } - if (lstrcmpi ("LANMANNT", szProductType) == 0) + if (lstrcmpiW(L"LANMANNT", szProductType) == 0) { // Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server. if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) @@ -5139,7 +5139,7 @@ bool SystemInformationImplementation::QueryOSInformation() this->OSRelease += " Server"; } } - if (lstrcmpi ("SERVERNT", szProductType) == 0) + if (lstrcmpiW(L"SERVERNT", szProductType) == 0) { // Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server. if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) @@ -5172,7 +5172,7 @@ bool SystemInformationImplementation::QueryOSInformation() LPFNPROC DLLProc; // Load the Kernel32 DLL. - hKernelDLL = LoadLibrary ("kernel32"); + hKernelDLL = LoadLibraryW(L"kernel32"); if (hKernelDLL != NULL) { // Only XP and .NET Server support IsWOW64Process so... Load dynamically! DLLProc = (LPFNPROC) GetProcAddress (hKernelDLL, "IsWow64Process"); diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 749002d..4649f3b 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -20,6 +20,8 @@ #include KWSYS_HEADER(RegularExpression.hxx) #include KWSYS_HEADER(SystemTools.hxx) #include KWSYS_HEADER(Directory.hxx) +#include KWSYS_HEADER(FStream.hxx) +#include KWSYS_HEADER(Encoding.hxx) #include KWSYS_HEADER(ios/iostream) #include KWSYS_HEADER(ios/fstream) @@ -32,6 +34,8 @@ #if 0 # include "SystemTools.hxx.in" # include "Directory.hxx.in" +# include "FStream.hxx.in" +# include "Encoding.hxx.in" # include "kwsys_ios_iostream.h.in" # include "kwsys_ios_fstream.h.in" # include "kwsys_ios_sstream.h.in" @@ -75,6 +79,9 @@ // Windows API. #if defined(_WIN32) # include <windows.h> +# ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +# endif #elif defined (__CYGWIN__) # include <windows.h> # undef _WIN32 @@ -183,22 +190,25 @@ static inline char *realpath(const char *path, char *resolved_path) #if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) inline int Mkdir(const char* dir) { - return _mkdir(dir); + return _wmkdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); } inline int Rmdir(const char* dir) { - return _rmdir(dir); + return _wrmdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); } inline const char* Getcwd(char* buf, unsigned int len) { - if(const char* ret = _getcwd(buf, len)) + std::vector<wchar_t> w_buf(len); + if(const wchar_t* ret = _wgetcwd(&w_buf[0], len)) { // make sure the drive letter is capital - if(strlen(buf) > 1 && buf[1] == ':') + if(wcslen(&w_buf[0]) > 1 && w_buf[1] == L':') { - buf[0] = toupper(buf[0]); + w_buf[0] = towupper(w_buf[0]); } - return ret; + std::string tmp = KWSYS_NAMESPACE::Encoding::ToNarrow(&w_buf[0]); + strcpy(buf, tmp.c_str()); + return buf; } return 0; } @@ -207,16 +217,18 @@ inline int Chdir(const char* dir) #if defined(__BORLANDC__) return chdir(dir); #else - return _chdir(dir); + return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); #endif } inline void Realpath(const char *path, kwsys_stl::string & resolved_path) { - char *ptemp; - char fullpath[MAX_PATH]; - if( GetFullPathName(path, sizeof(fullpath), fullpath, &ptemp) ) + kwsys_stl::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path); + wchar_t *ptemp; + wchar_t fullpath[MAX_PATH]; + if( GetFullPathNameW(tmp.c_str(), sizeof(fullpath)/sizeof(fullpath[0]), + fullpath, &ptemp) ) { - resolved_path = fullpath; + resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath); KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path); } else @@ -591,6 +603,15 @@ const char* SystemTools::GetExecutableExtension() #endif } +FILE* SystemTools::Fopen(const char* file, const char* mode) +{ +#ifdef _WIN32 + return _wfopen(Encoding::ToWide(file).c_str(), + Encoding::ToWide(mode).c_str()); +#else + return fopen(file, mode); +#endif +} bool SystemTools::MakeDirectory(const char* path) { @@ -740,7 +761,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode, SystemTools::KeyWOW64 view) { // only add the modes when on a system that supports Wow64. - static FARPROC wow64p = GetProcAddress(GetModuleHandle("kernel32"), + static FARPROC wow64p = GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); if(wow64p == NULL) { @@ -774,8 +795,8 @@ SystemTools::GetRegistrySubKeys(const char *key, } HKEY hKey; - if(RegOpenKeyEx(primaryKey, - second.c_str(), + if(RegOpenKeyExW(primaryKey, + Encoding::ToWide(second).c_str(), 0, SystemToolsMakeRegistryMode(KEY_READ, view), &hKey) != ERROR_SUCCESS) @@ -784,13 +805,13 @@ SystemTools::GetRegistrySubKeys(const char *key, } else { - char name[1024]; + wchar_t name[1024]; DWORD dwNameSize = sizeof(name)/sizeof(name[0]); DWORD i = 0; - while (RegEnumKey(hKey, i, name, dwNameSize) == ERROR_SUCCESS) + while (RegEnumKeyW(hKey, i, name, dwNameSize) == ERROR_SUCCESS) { - subkeys.push_back(name); + subkeys.push_back(Encoding::ToNarrow(name)); ++i; } @@ -829,8 +850,8 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, } HKEY hKey; - if(RegOpenKeyEx(primaryKey, - second.c_str(), + if(RegOpenKeyExW(primaryKey, + Encoding::ToWide(second).c_str(), 0, SystemToolsMakeRegistryMode(KEY_READ, view), &hKey) != ERROR_SUCCESS) @@ -841,9 +862,9 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, { DWORD dwType, dwSize; dwSize = 1023; - char data[1024]; - if(RegQueryValueEx(hKey, - (LPTSTR)valuename.c_str(), + wchar_t data[1024]; + if(RegQueryValueExW(hKey, + Encoding::ToWide(valuename).c_str(), NULL, &dwType, (BYTE *)data, @@ -851,16 +872,17 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, { if (dwType == REG_SZ) { - value = data; + value = Encoding::ToNarrow(data); valueset = true; } else if (dwType == REG_EXPAND_SZ) { - char expanded[1024]; + wchar_t expanded[1024]; DWORD dwExpandedSize = sizeof(expanded)/sizeof(expanded[0]); - if(ExpandEnvironmentStrings(data, expanded, dwExpandedSize)) + if(ExpandEnvironmentStringsW(data, expanded, + dwExpandedSize)) { - value = expanded; + value = Encoding::ToNarrow(expanded); valueset = true; } } @@ -901,9 +923,9 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, HKEY hKey; DWORD dwDummy; - char lpClass[] = ""; - if(RegCreateKeyEx(primaryKey, - second.c_str(), + wchar_t lpClass[] = L""; + if(RegCreateKeyExW(primaryKey, + Encoding::ToWide(second).c_str(), 0, lpClass, REG_OPTION_NON_VOLATILE, @@ -915,12 +937,13 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, return false; } - if(RegSetValueEx(hKey, - (LPTSTR)valuename.c_str(), + std::wstring wvalue = Encoding::ToWide(value); + if(RegSetValueExW(hKey, + Encoding::ToWide(valuename).c_str(), 0, REG_SZ, - (CONST BYTE *)value, - (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS) + (CONST BYTE *)wvalue.c_str(), + (DWORD)(sizeof(wchar_t) * (wvalue.size() + 1))) == ERROR_SUCCESS) { return true; } @@ -952,8 +975,8 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) } HKEY hKey; - if(RegOpenKeyEx(primaryKey, - second.c_str(), + if(RegOpenKeyExW(primaryKey, + Encoding::ToWide(second).c_str(), 0, SystemToolsMakeRegistryMode(KEY_WRITE, view), &hKey) != ERROR_SUCCESS) @@ -983,7 +1006,7 @@ bool SystemTools::SameFile(const char* file1, const char* file2) #ifdef _WIN32 HANDLE hFile1, hFile2; - hFile1 = CreateFile( file1, + hFile1 = CreateFileW( Encoding::ToWide(file1).c_str(), GENERIC_READ, FILE_SHARE_READ , NULL, @@ -991,7 +1014,7 @@ bool SystemTools::SameFile(const char* file1, const char* file2) FILE_FLAG_BACKUP_SEMANTICS, NULL ); - hFile2 = CreateFile( file2, + hFile2 = CreateFileW( Encoding::ToWide(file2).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, @@ -1040,15 +1063,6 @@ bool SystemTools::SameFile(const char* file1, const char* file2) } //---------------------------------------------------------------------------- -#if defined(_WIN32) || defined(__CYGWIN__) -static bool WindowsFileExists(const char* filename) -{ - WIN32_FILE_ATTRIBUTE_DATA fd; - return GetFileAttributesExA(filename, GetFileExInfoStandard, &fd) != 0; -} -#endif - -//---------------------------------------------------------------------------- bool SystemTools::FileExists(const char* filename) { if(!(filename && *filename)) @@ -1060,11 +1074,12 @@ bool SystemTools::FileExists(const char* filename) char winpath[MAX_PATH]; if(SystemTools::PathCygwinToWin32(filename, winpath)) { - return WindowsFileExists(winpath); + return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES); } return access(filename, R_OK) == 0; #elif defined(_WIN32) - return WindowsFileExists(filename); + return (GetFileAttributesW(Encoding::ToWide(filename).c_str()) + != INVALID_FILE_ATTRIBUTES); #else return access(filename, R_OK) == 0; #endif @@ -1107,7 +1122,7 @@ bool SystemTools::Touch(const char* filename, bool create) { if(create && !SystemTools::FileExists(filename)) { - FILE* file = fopen(filename, "a+b"); + FILE* file = Fopen(filename, "a+b"); if(file) { fclose(file); @@ -1116,7 +1131,8 @@ bool SystemTools::Touch(const char* filename, bool create) return false; } #if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE h = CreateFile(filename, FILE_WRITE_ATTRIBUTES, + HANDLE h = CreateFileW(Encoding::ToWide(filename).c_str(), + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if(!h) @@ -1220,11 +1236,13 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2, // Windows version. Get the modification time from extended file attributes. WIN32_FILE_ATTRIBUTE_DATA f1d; WIN32_FILE_ATTRIBUTE_DATA f2d; - if(!GetFileAttributesEx(f1, GetFileExInfoStandard, &f1d)) + if(!GetFileAttributesExW(Encoding::ToWide(f1).c_str(), + GetFileExInfoStandard, &f1d)) { return false; } - if(!GetFileAttributesEx(f2, GetFileExInfoStandard, &f2d)) + if(!GetFileAttributesExW(Encoding::ToWide(f2).c_str(), + GetFileExInfoStandard, &f2d)) { return false; } @@ -1932,6 +1950,39 @@ bool SystemTools::CopyFileIfDifferent(const char* source, bool SystemTools::FilesDiffer(const char* source, const char* destination) { + +#if defined(_WIN32) + WIN32_FILE_ATTRIBUTE_DATA statSource; + if (GetFileAttributesExW(Encoding::ToWide(source).c_str(), + GetFileExInfoStandard, + &statSource) == 0) + { + return true; + } + + WIN32_FILE_ATTRIBUTE_DATA statDestination; + if (GetFileAttributesExW(Encoding::ToWide(destination).c_str(), + GetFileExInfoStandard, + &statDestination) == 0) + { + return true; + } + + if(statSource.nFileSizeHigh != statDestination.nFileSizeHigh || + statSource.nFileSizeLow != statDestination.nFileSizeLow) + { + return true; + } + + if(statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) + { + return false; + } + off_t nleft = ((__int64)statSource.nFileSizeHigh << 32) + + statSource.nFileSizeLow; + +#else + struct stat statSource; if (stat(source, &statSource) != 0) { @@ -1953,15 +2004,19 @@ bool SystemTools::FilesDiffer(const char* source, { return false; } + off_t nleft = statSource.st_size; +#endif -#if defined(_WIN32) || defined(__CYGWIN__) - kwsys_ios::ifstream finSource(source, (kwsys_ios::ios::binary | - kwsys_ios::ios::in)); - kwsys_ios::ifstream finDestination(destination, (kwsys_ios::ios::binary | - kwsys_ios::ios::in)); +#if defined(_WIN32) + kwsys::ifstream finSource(source, + (kwsys_ios::ios::binary | + kwsys_ios::ios::in)); + kwsys::ifstream finDestination(destination, + (kwsys_ios::ios::binary | + kwsys_ios::ios::in)); #else - kwsys_ios::ifstream finSource(source); - kwsys_ios::ifstream finDestination(destination); + kwsys::ifstream finSource(source); + kwsys::ifstream finDestination(destination); #endif if(!finSource || !finDestination) { @@ -1971,7 +2026,6 @@ bool SystemTools::FilesDiffer(const char* source, // Compare the files a block at a time. char source_buf[KWSYS_ST_BUFFER]; char dest_buf[KWSYS_ST_BUFFER]; - off_t nleft = statSource.st_size; while(nleft > 0) { // Read a block from each file. @@ -2044,10 +2098,10 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination) // Open files #if defined(_WIN32) || defined(__CYGWIN__) - kwsys_ios::ifstream fin(source, - kwsys_ios::ios::binary | kwsys_ios::ios::in); + kwsys::ifstream fin(source, + kwsys_ios::ios::binary | kwsys_ios::ios::in); #else - kwsys_ios::ifstream fin(source); + kwsys::ifstream fin(source); #endif if(!fin) { @@ -2344,7 +2398,11 @@ bool SystemTools::RemoveFile(const char* source) /* Win32 unlink is stupid --- it fails if the file is read-only */ SystemTools::SetPermissions(source, S_IWRITE); #endif +#ifdef _WIN32 + bool res = _wunlink(Encoding::ToWide(source).c_str()) != 0 ? false : true; +#else bool res = unlink(source) != 0 ? false : true; +#endif #ifdef _WIN32 if ( !res ) { @@ -2789,12 +2847,15 @@ bool SystemTools::FileIsDirectory(const char* name) } // Now check the file node type. +#if defined( _WIN32 ) + DWORD attr = GetFileAttributesW(Encoding::ToWide(name).c_str()); + if (attr != INVALID_FILE_ATTRIBUTES) + { + return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; +#else struct stat fs; if(stat(name, &fs) == 0) { -#if defined( _WIN32 ) && !defined(__CYGWIN__) - return ((fs.st_mode & _S_IFDIR) != 0); -#else return S_ISDIR(fs.st_mode); #endif } @@ -3279,11 +3340,12 @@ static int GetCasePathName(const kwsys_stl::string & pathIn, kwsys_stl::string test_str = casePath; test_str += path_components[idx]; - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile(test_str.c_str(), &findData); + WIN32_FIND_DATAW findData; + HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), + &findData); if (INVALID_HANDLE_VALUE != hFind) { - casePath += findData.cFileName; + casePath += Encoding::ToNarrow(findData.cFileName); ::FindClose(hFind); } else @@ -3733,8 +3795,7 @@ bool SystemTools::FileHasSignature(const char *filename, return false; } - FILE *fp; - fp = fopen(filename, "rb"); + FILE *fp = Fopen(filename, "rb"); if (!fp) { return false; @@ -3767,8 +3828,7 @@ SystemTools::DetectFileType(const char *filename, return SystemTools::FileTypeUnknown; } - FILE *fp; - fp = fopen(filename, "rb"); + FILE *fp = Fopen(filename, "rb"); if (!fp) { return SystemTools::FileTypeUnknown; @@ -3958,9 +4018,8 @@ bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath) { #if defined(WIN32) && !defined(__CYGWIN__) const int size = int(strlen(path)) +1; // size of return - char *buffer = new char[size]; // create a buffer char *tempPath = new char[size]; // create a buffer - int ret; + DWORD ret; // if the path passed in has quotes around it, first remove the quotes if (path[0] == '"' && path[strlen(path)-1] == '"') @@ -3973,19 +4032,20 @@ bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath) strcpy(tempPath,path); } + kwsys_stl::wstring wtempPath = Encoding::ToWide(tempPath); + kwsys_stl::vector<wchar_t> buffer(wtempPath.size()+1); buffer[0] = 0; - ret = GetShortPathName(tempPath, buffer, size); + ret = GetShortPathNameW(Encoding::ToWide(tempPath).c_str(), + &buffer[0], static_cast<DWORD>(wtempPath.size())); - if(buffer[0] == 0 || ret > size) + if(buffer[0] == 0 || ret > wtempPath.size()) { - delete [] buffer; delete [] tempPath; return false; } else { - shortPath = buffer; - delete [] buffer; + shortPath = Encoding::ToNarrow(&buffer[0]); delete [] tempPath; return true; } @@ -4212,12 +4272,45 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode) return false; } +#if defined(_WIN32) + DWORD attr = GetFileAttributesW(Encoding::ToWide(file).c_str()); + if(attr == INVALID_FILE_ATTRIBUTES) + { + return false; + } + if((attr & FILE_ATTRIBUTE_READONLY) != 0) + { + mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); + } + else + { + mode = (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6)) | + (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); + } + if((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + mode |= S_IFDIR | (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6)); + } + else + { + mode |= S_IFREG; + } + const char* ext = strrchr(file, '.'); + if(ext && (Strucmp(ext, ".exe") == 0 || + Strucmp(ext, ".com") == 0 || + Strucmp(ext, ".cmd") == 0 || + Strucmp(ext, ".bat") == 0)) + { + mode |= (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6)); + } +#else struct stat st; if ( stat(file, &st) < 0 ) { return false; } mode = st.st_mode; +#endif return true; } @@ -4231,7 +4324,11 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode) { return false; } +#ifdef _WIN32 + if ( _wchmod(Encoding::ToWide(file).c_str(), mode) < 0 ) +#else if ( chmod(file, mode) < 0 ) +#endif { return false; } @@ -4336,7 +4433,9 @@ void SystemTools::ConvertWindowsCommandLineToUnixArguments( (*argv)[0] = new char [1024]; #ifdef _WIN32 - ::GetModuleFileName(0, (*argv)[0], 1024); + wchar_t tmp[1024]; + ::GetModuleFileNameW(0, tmp, 1024); + strcpy((*argv)[0], Encoding::ToNarrow(tmp).c_str()); #else (*argv)[0][0] = '\0'; #endif @@ -4396,14 +4495,14 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() #ifdef _WIN32 char buffer[256]; - OSVERSIONINFOEX osvi; + OSVERSIONINFOEXA osvi; BOOL bOsVersionInfoEx; // Try calling GetVersionEx using the OSVERSIONINFOEX structure. // If that fails, try using the OSVERSIONINFO structure. - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi); if (!bOsVersionInfoEx) @@ -4546,21 +4645,21 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() { HKEY hKey; #define BUFSIZE 80 - char szProductType[BUFSIZE]; + wchar_t szProductType[BUFSIZE]; DWORD dwBufLen=BUFSIZE; LONG lRet; - lRet = RegOpenKeyEx( + lRet = RegOpenKeyExW( HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", + L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey); if (lRet != ERROR_SUCCESS) { return 0; } - lRet = RegQueryValueEx(hKey, "ProductType", NULL, NULL, - (LPBYTE) szProductType, &dwBufLen); + lRet = RegQueryValueExW(hKey, L"ProductType", NULL, NULL, + (LPBYTE) szProductType, &dwBufLen); if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE)) { @@ -4569,15 +4668,15 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() RegCloseKey(hKey); - if (lstrcmpi("WINNT", szProductType) == 0) + if (lstrcmpiW(L"WINNT", szProductType) == 0) { res += " Workstation"; } - if (lstrcmpi("LANMANNT", szProductType) == 0) + if (lstrcmpiW(L"LANMANNT", szProductType) == 0) { res += " Server"; } - if (lstrcmpi("SERVERNT", szProductType) == 0) + if (lstrcmpiW(L"SERVERNT", szProductType) == 0) { res += " Advanced Server"; } @@ -4593,16 +4692,16 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() // Display service pack (if any) and build number. if (osvi.dwMajorVersion == 4 && - lstrcmpi(osvi.szCSDVersion, "Service Pack 6") == 0) + lstrcmpiA(osvi.szCSDVersion, "Service Pack 6") == 0) { HKEY hKey; LONG lRet; // Test for SP6 versus SP6a. - lRet = RegOpenKeyEx( + lRet = RegOpenKeyExW( HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", 0, KEY_QUERY_VALUE, &hKey); if (lRet == ERROR_SUCCESS) diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index d6dae39..9457a4e 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -24,6 +24,8 @@ // Required for va_list #include <stdarg.h> +// Required for FILE* +#include <stdio.h> #if @KWSYS_NAMESPACE@_STL_HAVE_STD && !defined(va_list) // Some compilers move va_list into the std namespace and there is no way to // tell that this has been done. Playing with things being included before or @@ -42,10 +44,6 @@ namespace @KWSYS_NAMESPACE@ } #endif // va_list -#if defined( _MSC_VER ) -typedef unsigned short mode_t; -#endif - /* Define these macros temporarily to keep the code readable. */ #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS # define kwsys_stl @KWSYS_NAMESPACE@_stl @@ -497,6 +495,11 @@ public: */ /** + * Open a file considering unicode. + */ + static FILE* Fopen(const char* file, const char* mode); + + /** * Make a new directory if it is not there. This function * can make a full path even if none of the directories existed * prior to calling this function. @@ -684,6 +687,10 @@ public: */ static long int CreationTime(const char* filename); + #if defined( _MSC_VER ) + typedef unsigned short mode_t; + #endif + /** * Get and set permissions of the file. */ diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index be7a09e..3f947f3 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -674,3 +674,9 @@ int main() return a; } #endif + +#ifdef TEST_KWSYS_STL_HAS_WSTRING +#include <string> +void f(std ::wstring*) {} +int main() { return 0; } +#endif diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx new file mode 100644 index 0000000..8e74a50 --- /dev/null +++ b/Source/kwsys/testEncoding.cxx @@ -0,0 +1,159 @@ +/*============================================================================ + KWSys - Kitware System Library + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "kwsysPrivate.h" + +#if defined(_MSC_VER) +# pragma warning (disable:4786) +#endif + +#include KWSYS_HEADER(Encoding.hxx) +#include KWSYS_HEADER(ios/iostream) + +#include <locale.h> + +// Work-around CMake dependency scanning limitation. This must +// duplicate the above list of headers. +#if 0 +# include "Encoding.hxx.in" +# include "kwsys_ios_iostream.h.in" +#endif + +//---------------------------------------------------------------------------- +static const unsigned char helloWorldStrings[][32] = +{ + // English + {'H','e','l','l','o',' ','W','o','r','l','d',0}, + // Japanese + {0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3, + 0x81, 0xA1, 0xE3, 0x81, 0xAF, 0xE4, 0xB8, 0x96, 0xE7, 0x95, + 0x8C, 0}, + // Arabic + {0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7, + 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD8, 0xB9, 0xD8, 0xA7, 0xD9, + 0x84, 0xD9, 0x85, 0}, + // Yiddish + {0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x90, 0x20, 0xD7, + 0x95, 0xD7, 0x95, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98, 0}, + // Russian + {0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, + 0xD1, 0x82, 0x20, 0xD0, 0xBC, 0xD0, 0xB8, 0xD1, 0x80, 0}, + // Latin + {0x4D, 0x75, 0x6E, 0x64, 0x75, 0x73, 0x20, 0x73, 0x61, 0x6C, + 0x76, 0x65, 0}, + // Swahili + {0x68, 0x75, 0x6A, 0x61, 0x6D, 0x62, 0x6F, 0x20, 0x44, 0x75, + 0x6E, 0x69, 0x61, 0}, + // Icelandic + {0x48, 0x61, 0x6C, 0x6C, 0xC3, 0xB3, 0x20, 0x68, 0x65, 0x69, + 0x6D, 0x75, 0x72, 0}, + {0} +}; + +//---------------------------------------------------------------------------- +static int testHelloWorldEncoding() +{ + int ret = 0; + for(int i=0; helloWorldStrings[i][0] != 0; i++) + { + std::string str = reinterpret_cast<const char*>(helloWorldStrings[i]); + std::cout << str << std::endl; + std::wstring wstr = kwsys::Encoding::ToWide(str); + std::string str2 = kwsys::Encoding::ToNarrow(wstr); + if(!wstr.empty() && str != str2) + { + std::cout << "converted string was different: " << str2 << std::endl; + ret++; + } + } + return ret; +} + +static int testRobustEncoding() +{ + // test that the conversion functions handle invalid + // unicode correctly/gracefully + + int ret = 0; + char cstr[] = {(char)-1, 0}; + // this conversion could fail + std::wstring wstr = kwsys::Encoding::ToWide(cstr); + + wstr = kwsys::Encoding::ToWide(NULL); + if(wstr != L"") + { + const wchar_t* wcstr = wstr.c_str(); + std::cout << "ToWide(NULL) returned"; + for(size_t i=0; i<wstr.size(); i++) + { + std::cout << " " << std::hex << (int)wcstr[i]; + } + std::cout << std::endl; + ret++; + } + wstr = kwsys::Encoding::ToWide(""); + if(wstr != L"") + { + const wchar_t* wcstr = wstr.c_str(); + std::cout << "ToWide(\"\") returned"; + for(size_t i=0; i<wstr.size(); i++) + { + std::cout << " " << std::hex << (int)wcstr[i]; + } + std::cout << std::endl; + ret++; + } + +#ifdef WIN32 + // 16 bit wchar_t - we make an invalid surrogate pair + wchar_t cwstr[] = {0xD801, 0xDA00, 0}; + // this conversion could fail + std::string win_str = kwsys::Encoding::ToNarrow(cwstr); +#endif + + std::string str = kwsys::Encoding::ToNarrow(NULL); + if(str != "") + { + std::cout << "ToNarrow(NULL) returned " << str << std::endl; + ret++; + } + + str = kwsys::Encoding::ToNarrow(L""); + if(wstr != L"") + { + std::cout << "ToNarrow(\"\") returned " << str << std::endl; + ret++; + } + + return ret; +} + + +//---------------------------------------------------------------------------- +int testEncoding(int, char*[]) +{ + const char* loc = setlocale(LC_ALL, ""); + if(loc) + { + std::cout << "Locale: " << loc << std::endl; + } + else + { + std::cout << "Locale: None" << std::endl; + } + + int ret = 0; + + ret |= testHelloWorldEncoding(); + ret |= testRobustEncoding(); + + return ret; +} |