From cc7d2db338430447f6ee5a360cfa14e99e1a1dcc Mon Sep 17 00:00:00 2001 From: KWSys Upstream Date: Sat, 23 Nov 2024 15:14:49 -0500 Subject: [PATCH] KWSys 2024-11-23 (3e9b0b88) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code extracted from: https://gitlab.kitware.com/utils/kwsys.git at commit 3e9b0b88c2284302a26073d30aafaffe8c99f320 (master). Upstream Shortlog ----------------- Ben Boeckel (1): 72e677e9 kwsysPrivate.h: Remove unused build-tree copy Brad King (11): 9f9ff427 SystemTools: Teach RemoveADirectory to handle non-readable directories 3c922475 Convert http URLs to https beaf1ca1 ConsoleBuf: Fix test case when running under Windows Terminal 4feb470a SystemTools: Remove GetActualCaseForPath from CollapseFullPath 6e847d08 SystemInformation: Add missing EOF check when reading /proc/cpuinfo 741c9c96 SystemTools: Expose GetActualCaseForPathCached publicly fdf4f2f8 SystemTools: Fix ReadSymlink for links to absolute paths on Windows 20b2c992 SystemTools: Remove unused global object 47dce1a3 SystemTools: Remove path translation map 30e9db2d SystemTools: Drop GetActualCaseForPathCached 5995fd7d SystemInformation: Ignore stderr from OS query tools Christoph GrĂ¼ninger (3): d3f3c38b Use prefix ++ operators for non-primitive types 9fd52415 Range-for loop with const reference 2310be95 Make variable more local Clemens Wasser (1): dd7d92d6 SystemTools: Implement GetEnv via GetEnvironmentVariableW on Win32 Daniel Pfeifer (1): 68e1f35d SystemInformation: fix use of using Jochem van Boxtel (1): 510b13b4 SystemTools: Add FileId class and GetFileId function Juan Ramos (2): ff14b4f5 SystemInformation: Fix find logic a347a66b SystemInformation: Implement HasFPU on Apple processors Mike Lundy (1): ee3223d7 SystemTools: fix clonefile optimization on macOS scivision (11): 12825be6 lint: use foreach(... IN {ITEMS,LISTS} ...) f10cb6ad lint: use modern add_test(NAME ... COMMAND ...) ebb95153 lint: set_property(TEST f26b1b39 SystemInformation: use std::cerr like rest of KWSys 3c403fa9 SystemInformation: Replace C-style cast with reinterpret_cast 7f4459d5 Comeau: Remove undocumented support for this compiler 6624edf2 SystemTools:FileIs{Directory,Executable,FIFO}: refactor for simplicity 5f4012c6 Don't compare to nullptr 3f14fce6 Process: Replace 0 with NULL in pointer arguments to GetFullPathNameW 210cea0a SystemTools: Replace unused argument to GetFullPathNameW with nullptr f5e82d63 SystemTools: Replace malloc() with std::string --- CMakeLists.txt | 54 ++--- CONTRIBUTING.rst | 2 +- CommandLineArguments.cxx | 16 +- Configure.hxx.in | 5 - Directory.cxx | 10 +- MD5.c | 2 +- ProcessUNIX.c | 2 +- ProcessWin32.c | 4 +- RegularExpression.cxx | 56 ++--- RegularExpression.hxx.in | 6 +- SystemInformation.cxx | 138 +++++-------- SystemTools.cxx | 426 ++++++++++++--------------------------- SystemTools.hxx.in | 72 ++++--- Terminal.c | 4 +- testConsoleBuf.cxx | 26 ++- testSystemTools.cxx | 4 +- 16 files changed, 322 insertions(+), 505 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b8eedd4e9..be510b1947 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,14 +298,6 @@ endif() set(KWSYS_HEADER_INSTALL_DIR) set(KWSYS_LIBRARY_INSTALL_DIR) -# Generated source files will need this header. -string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" - KWSYS_IN_SOURCE_BUILD) -if(NOT KWSYS_IN_SOURCE_BUILD) - configure_file(${PROJECT_SOURCE_DIR}/kwsysPrivate.h - ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE) -endif() - # Select plugin module file name convention. if(NOT KWSYS_DynamicLoader_PREFIX) set(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX}) @@ -418,14 +410,6 @@ if(KWSYS_USE_DynamicLoader) endif() if(KWSYS_USE_SystemTools) - if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP) - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1) - endif () - if (KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP) - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1) - else () - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 0) - endif () KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV "Checking whether CXX compiler has setenv" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UNSETENV @@ -634,7 +618,7 @@ set(cppclasses Directory DynamicLoader Encoding Glob RegularExpression SystemTools CommandLineArguments FStream SystemInformation ConsoleBuf Status ) -foreach(cpp ${cppclasses}) +foreach(cpp IN LISTS cppclasses) if(KWSYS_USE_${cpp}) # Use the corresponding class. set(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp}) @@ -647,7 +631,7 @@ foreach(cpp ${cppclasses}) endforeach() # Add selected C components. -foreach(c +foreach(c IN ITEMS Process Base64 Encoding MD5 Terminal System String ) if(KWSYS_USE_${c}) @@ -679,7 +663,7 @@ if(KWSYS_USE_Process) endif() # Add selected C sources. -foreach(c Base64 Encoding MD5 Terminal System String) +foreach(c IN ITEMS Base64 Encoding MD5 Terminal System String) if(KWSYS_USE_${c}) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c) list(APPEND KWSYS_C_SRCS ${c}C.c) @@ -690,7 +674,7 @@ foreach(c Base64 Encoding MD5 Terminal System String) endforeach() # Configure headers of C++ classes and construct the list of sources. -foreach(c ${KWSYS_CLASSES}) +foreach(c IN LISTS KWSYS_CLASSES) # Add this source to the list of source files for the library. if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx) list(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx) @@ -712,7 +696,7 @@ foreach(c ${KWSYS_CLASSES}) endforeach() # Configure C headers. -foreach(h ${KWSYS_H_FILES}) +foreach(h IN LISTS KWSYS_H_FILES) # Configure the header into the given directory. configure_file(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h @ONLY IMMEDIATE) @@ -727,7 +711,7 @@ foreach(h ${KWSYS_H_FILES}) endforeach() # Configure other C++ headers. -foreach(h ${KWSYS_HXX_FILES}) +foreach(h IN LISTS KWSYS_HXX_FILES) # Configure the header into the given directory. configure_file(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx @ONLY IMMEDIATE) @@ -956,9 +940,11 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) add_executable(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS}) set_property(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE}) target_link_libraries(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK}) - foreach(testfile ${KWSYS_C_TESTS}) + foreach(testfile IN LISTS KWSYS_C_TESTS) get_filename_component(test "${testfile}" NAME_WE) - add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}}) + add_test(NAME kwsys.${test} + COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}} + ) set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) endforeach() @@ -1080,9 +1066,11 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) -p some junk at the end ) - foreach(testfile ${KWSYS_CXX_TESTS}) + foreach(testfile IN LISTS KWSYS_CXX_TESTS) get_filename_component(test "${testfile}" NAME_WE) - add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}}) + add_test(NAME kwsys.${test} + COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}} + ) set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) endforeach() @@ -1091,10 +1079,12 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) set_property(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE}) target_link_libraries(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK}) #set(KWSYS_TEST_PROCESS_7 7) # uncomment to run timing-sensitive test locally - foreach(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10) - add_test(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}) + foreach(n IN ITEMS 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10) + add_test(NAME kwsys.testProcess-${n} + COMMAND ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n} + ) set_property(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - set_tests_properties(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120) + set_property(TEST kwsys.testProcess-${n} PROPERTY TIMEOUT 120) endforeach() set(testProcess_COMPILE_FLAGS "") @@ -1121,9 +1111,9 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # Configure some test properties. if(KWSYS_STANDALONE) # We expect test to fail - set_tests_properties(kwsys.testFail PROPERTIES WILL_FAIL ON) + set_property(TEST kwsys.testFail PROPERTY WILL_FAIL ON) get_test_property(kwsys.testFail WILL_FAIL wfv) - set_tests_properties(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value") + set_property(TEST kwsys.testFail PROPERTY MEASUREMENT "Some Key=Some Value") message(STATUS "GET_TEST_PROPERTY returned: ${wfv}") endif() @@ -1133,7 +1123,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # Suppress known consistent failures on buggy systems. if(KWSYS_TEST_BOGUS_FAILURES) - set_tests_properties(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON) + set_property(TEST ${KWSYS_TEST_BOGUS_FAILURES} PROPERTY WILL_FAIL ON) endif() endif() diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ebd3ed355a..d62afa5751 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -34,7 +34,7 @@ code. It automatically runs ``clang-format`` on the set of source files for which we enforce style. The script also has options to format only a subset of files, such as those that are locally modified. -.. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html +.. _`clang-format`: https://clang.llvm.org/docs/ClangFormat.html .. _`.clang-format`: .clang-format .. _`clang-format.bash`: clang-format.bash diff --git a/CommandLineArguments.cxx b/CommandLineArguments.cxx index 50171dd3c6..61703ada26 100644 --- a/CommandLineArguments.cxx +++ b/CommandLineArguments.cxx @@ -132,7 +132,7 @@ bool CommandLineArguments::GetMatchedArguments( // Does the argument match to any we know about? for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { + it != this->Internals->Callbacks.end(); ++it) { const CommandLineArguments::Internal::String& parg = it->first; CommandLineArgumentsCallbackStructure* cs = &it->second; if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT || @@ -467,7 +467,7 @@ void CommandLineArguments::GenerateHelp() MapArgs mp; MapArgs::iterator mpit, smpit; for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { + it != this->Internals->Callbacks.end(); ++it) { CommandLineArgumentsCallbackStructure* cs = &(it->second); mpit = mp.find(cs->Help); if (mpit != mp.end()) { @@ -478,14 +478,14 @@ void CommandLineArguments::GenerateHelp() } } for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { + it != this->Internals->Callbacks.end(); ++it) { CommandLineArgumentsCallbackStructure* cs = &(it->second); mpit = mp.find(cs->Help); if (mpit != mp.end()) { mpit->second.insert(it->first); smpit = mp.find(it->first); CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = smpit->second.begin(); sit != smpit->second.end(); sit++) { + for (sit = smpit->second.begin(); sit != smpit->second.end(); ++sit) { mpit->second.insert(*sit); } mp.erase(smpit); @@ -496,9 +496,9 @@ void CommandLineArguments::GenerateHelp() // Find the length of the longest string CommandLineArguments::Internal::String::size_type maxlen = 0; - for (mpit = mp.begin(); mpit != mp.end(); mpit++) { + for (mpit = mp.begin(); mpit != mp.end(); ++mpit) { CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { + for (sit = mpit->second.begin(); sit != mpit->second.end(); ++sit) { CommandLineArguments::Internal::String::size_type clen = sit->size(); switch (this->Internals->Callbacks[*sit].ArgumentType) { case CommandLineArguments::NO_ARGUMENT: @@ -524,9 +524,9 @@ void CommandLineArguments::GenerateHelp() maxlen += 4; // For the space before and after the option // Print help for each option - for (mpit = mp.begin(); mpit != mp.end(); mpit++) { + for (mpit = mp.begin(); mpit != mp.end(); ++mpit) { CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { + for (sit = mpit->second.begin(); sit != mpit->second.end(); ++sit) { str << std::endl; std::string argument = *sit; switch (this->Internals->Callbacks[*sit].ArgumentType) { diff --git a/Configure.hxx.in b/Configure.hxx.in index 8d47340594..b4b0efaa94 100644 --- a/Configure.hxx.in +++ b/Configure.hxx.in @@ -11,9 +11,6 @@ /* Whether is available. */ #define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \ @KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@ -/* Whether the translation map is available or not. */ -#define @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP \ - @KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP@ #if defined(__SUNPRO_CC) && __SUNPRO_CC > 0x5130 && defined(__has_attribute) # define @KWSYS_NAMESPACE@_has_cpp_attribute(x) __has_attribute(x) @@ -58,8 +55,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_SYSTEMTOOLS_USE_TRANSLATION_MAP \ - @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP #endif #endif diff --git a/Directory.cxx b/Directory.cxx index f239576efe..6e4f0a8c3d 100644 --- a/Directory.cxx +++ b/Directory.cxx @@ -269,7 +269,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, # include // PGI with glibc has trouble with dirent and large file support: -// http://www.pgroup.com/userforum/viewtopic.php? +// https://www.pgroup.com/userforum/viewtopic.php? // p=1992&sid=f16167f51964f1a68fe5041b8eb213b6 // Work around the problem by mapping dirent the same way as readdir. # if defined(__PGI) && defined(__GLIBC__) @@ -292,7 +292,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage) DIR* dir = opendir(name.c_str()); if (!dir) { - if (errorMessage != nullptr) { + if (errorMessage) { *errorMessage = std::string(strerror(errno)); } return Status::POSIX_errno(); @@ -303,7 +303,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage) this->Internal->Files.emplace_back(d->d_name); } if (errno != 0) { - if (errorMessage != nullptr) { + if (errorMessage) { *errorMessage = std::string(strerror(errno)); } return Status::POSIX_errno(); @@ -321,7 +321,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, DIR* dir = opendir(name.c_str()); if (!dir) { - if (errorMessage != nullptr) { + if (errorMessage) { *errorMessage = std::string(strerror(errno)); } return 0; @@ -332,7 +332,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, count++; } if (errno != 0) { - if (errorMessage != nullptr) { + if (errorMessage) { *errorMessage = std::string(strerror(errno)); } return false; diff --git a/MD5.c b/MD5.c index 76995e22f0..b0faa0ebca 100644 --- a/MD5.c +++ b/MD5.c @@ -52,7 +52,7 @@ This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at - http://www.ietf.org/rfc/rfc1321.txt + https://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being diff --git a/ProcessUNIX.c b/ProcessUNIX.c index b25b2580d2..efe22334f2 100644 --- a/ProcessUNIX.c +++ b/ProcessUNIX.c @@ -2541,7 +2541,7 @@ static void kwsysProcessKill(pid_t process_id) /* Kill all children if we can find them. */ #if defined(__linux__) || defined(__CYGWIN__) /* First try using the /proc filesystem. */ - if ((procdir = opendir("/proc")) != NULL) { + if ((procdir = opendir("/proc"))) { # if defined(MAXPATHLEN) char fname[MAXPATHLEN]; # elif defined(PATH_MAX) diff --git a/ProcessWin32.c b/ProcessWin32.c index 0b43b4a2af..c1a566f4ad 100644 --- a/ProcessWin32.c +++ b/ProcessWin32.c @@ -666,14 +666,14 @@ 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 = GetFullPathNameW(wdir, 0, 0, 0); + DWORD length = GetFullPathNameW(wdir, 0, NULL, NULL); if (length > 0) { wchar_t* work_dir = malloc(length * sizeof(wchar_t)); if (!work_dir) { free(wdir); return 0; } - if (!GetFullPathNameW(wdir, length, work_dir, 0)) { + if (!GetFullPathNameW(wdir, length, work_dir, NULL)) { free(work_dir); free(wdir); return 0; diff --git a/RegularExpression.cxx b/RegularExpression.cxx index b51e16d8ae..75e7442c28 100644 --- a/RegularExpression.cxx +++ b/RegularExpression.cxx @@ -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 != nullptr) { + if (rxp.regmust) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -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 != nullptr) { + if (rxp.regmust) { char* dum = rxp.program; ind = 0; while (dum != rxp.regmust) { @@ -339,7 +339,7 @@ bool RegularExpression::compile(const char* exp) const char* longest; int flags; - if (exp == nullptr) { + if (!exp) { // RAISE Error, SYM(RegularExpression), SYM(No_Expr), printf("RegularExpression::compile(): No expression supplied.\n"); return false; @@ -372,7 +372,7 @@ bool RegularExpression::compile(const char* exp) this->program = new char[comp.regsize]; this->progsize = static_cast(comp.regsize); - if (this->program == nullptr) { + if (!this->program) { // RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory), printf("RegularExpression::compile(): Out of memory.\n"); return false; @@ -415,7 +415,7 @@ bool RegularExpression::compile(const char* exp) if (flags & SPSTART) { longest = nullptr; size_t len = 0; - for (; scan != nullptr; scan = regnext(scan)) + for (; scan; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); @@ -461,9 +461,9 @@ char* RegExpCompile::reg(int paren, int* flagp) // Pick up the branches, linking them together. br = regbranch(&flags); - if (br == nullptr) + if (!br) return (nullptr); - if (ret != nullptr) + if (ret) regtail(ret, br); // OPEN -> first. else ret = br; @@ -473,7 +473,7 @@ char* RegExpCompile::reg(int paren, int* flagp) while (*regparse == '|') { regparse++; br = regbranch(&flags); - if (br == nullptr) + if (!br) return (nullptr); regtail(ret, br); // BRANCH -> BRANCH. if (!(flags & HASWIDTH)) @@ -486,7 +486,7 @@ char* RegExpCompile::reg(int paren, int* flagp) regtail(ret, ender); // Hook the tails of the branches to the closing node. - for (br = ret; br != nullptr; br = regnext(br)) + for (br = ret; br; br = regnext(br)) regoptail(br, ender); // Check for proper termination. @@ -527,16 +527,16 @@ char* RegExpCompile::regbranch(int* flagp) chain = nullptr; while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { latest = regpiece(&flags); - if (latest == nullptr) + if (!latest) return (nullptr); *flagp |= flags & HASWIDTH; - if (chain == nullptr) // First piece. + if (!chain) // First piece. *flagp |= flags & SPSTART; else regtail(chain, latest); chain = latest; } - if (chain == nullptr) // Loop ran zero times. + if (!chain) // Loop ran zero times. regnode(NOTHING); return (ret); @@ -559,7 +559,7 @@ char* RegExpCompile::regpiece(int* flagp) int flags; ret = regatom(&flags); - if (ret == nullptr) + if (!ret) return (nullptr); op = *regparse; @@ -678,7 +678,7 @@ char* RegExpCompile::regatom(int* flagp) } break; case '(': ret = reg(1, &flags); - if (ret == nullptr) + if (!ret) return (nullptr); *flagp |= flags & (HASWIDTH | SPSTART); break; @@ -812,7 +812,7 @@ void RegExpCompile::regtail(char* p, const char* val) scan = p; for (;;) { temp = regnext(scan); - if (temp == nullptr) + if (!temp) break; scan = temp; } @@ -831,7 +831,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 == nullptr || p == regdummyptr || OP(p) != BRANCH) + if (!p || p == regdummyptr || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } @@ -881,14 +881,14 @@ bool RegularExpression::find(char const* string, } // If there is a "must appear" string, look for it. - if (this->regmust != nullptr) { + if (this->regmust) { s = string; - while ((s = strchr(s, this->regmust[0])) != nullptr) { + while ((s = strchr(s, this->regmust[0]))) { if (strncmp(s, this->regmust, this->regmlen) == 0) break; // Found it. s++; } - if (s == nullptr) // Not present. + if (!s) // Not present. return false; } @@ -906,7 +906,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)) != nullptr) { + while ((s = strchr(s, this->regstart))) { if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program)) return true; s++; @@ -969,7 +969,7 @@ int RegExpFind::regmatch(const char* prog) scan = prog; - while (scan != nullptr) { + while (scan) { next = regnext(scan); @@ -1001,12 +1001,12 @@ int RegExpFind::regmatch(const char* prog) reginput += len; } break; case ANYOF: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == nullptr) + if (*reginput == '\0' || !strchr(OPERAND(scan), *reginput)) return (0); reginput++; break; case ANYBUT: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != nullptr) + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput)) return (0); reginput++; break; @@ -1058,7 +1058,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set startp if some later invocation of the // same parentheses already has. // - if (regstartp[no] == nullptr) + if (!regstartp[no]) regstartp[no] = save; return (1); } else @@ -1109,7 +1109,7 @@ int RegExpFind::regmatch(const char* prog) // Don't set endp if some later invocation of the // same parentheses already has. // - if (regendp[no] == nullptr) + if (!regendp[no]) regendp[no] = save; return (1); } else @@ -1129,7 +1129,7 @@ int RegExpFind::regmatch(const char* prog) return (1); reginput = save; scan = regnext(scan); - } while (scan != nullptr && OP(scan) == BRANCH); + } while (scan && OP(scan) == BRANCH); return (0); // NOTREACHED } @@ -1207,13 +1207,13 @@ int RegExpFind::regrepeat(const char* p) } break; case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != nullptr) { + while (*scan != '\0' && strchr(opnd, *scan)) { count++; scan++; } break; case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == nullptr) { + while (*scan != '\0' && !strchr(opnd, *scan)) { count++; scan++; } diff --git a/RegularExpression.hxx.in b/RegularExpression.hxx.in index 1dc1dfa208..d73482b042 100644 --- a/RegularExpression.hxx.in +++ b/RegularExpression.hxx.in @@ -86,7 +86,7 @@ inline RegularExpressionMatch::RegularExpressionMatch() */ inline bool RegularExpressionMatch::isValid() const { - return (this->startp[0] != nullptr); + return (this->startp[0]); } /** @@ -140,7 +140,7 @@ inline std::string::size_type RegularExpressionMatch::end(int n) const */ inline std::string RegularExpressionMatch::match(int n) const { - if (this->startp[n] == nullptr) { + if (!this->startp[n]) { return std::string(); } else { return std::string( @@ -551,7 +551,7 @@ inline bool RegularExpression::operator!=(const RegularExpression& r) const */ inline bool RegularExpression::is_valid() const { - return (this->program != nullptr); + return (this->program); } inline void RegularExpression::set_invalid() diff --git a/SystemInformation.cxx b/SystemInformation.cxx index 7f8485e752..7b0d271196 100644 --- a/SystemInformation.cxx +++ b/SystemInformation.cxx @@ -22,10 +22,10 @@ // Consider using these on Win32/Win64 for some of them: // // IsProcessorFeaturePresent -// http://msdn.microsoft.com/en-us/library/ms724482(VS.85).aspx +// https://msdn.microsoft.com/en-us/library/ms724482(VS.85).aspx // // GetProcessMemoryInfo -// http://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx +// https://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx #include "kwsysPrivate.h" #include KWSYS_HEADER(SystemInformation.hxx) @@ -59,7 +59,7 @@ # include # endif # if !defined(siginfo_t) -typedef int siginfo_t; +using siginfo_t = int; # endif #else # include @@ -135,7 +135,7 @@ typedef int siginfo_t; using ResourceLimitType = struct rlimit64; # define GetResourceLimit getrlimit64 # else -typedef struct rlimit ResourceLimitType; +using ResourceLimitType = struct rlimit; # define GetResourceLimit getrlimit # endif #elif defined(__hpux) @@ -333,101 +333,58 @@ class SystemInformationImplementation void RunMemoryCheck(); public: - using ID = struct tagID - + struct ID { - int Type; - int Family; - int Model; - int Revision; - int ExtendedFamily; - int ExtendedModel; - std::string ProcessorName; - std::string Vendor; - std::string SerialNumber; - std::string ModelName; }; - using CPUPowerManagement = struct tagCPUPowerManagement - + struct CPUPowerManagement { - bool HasVoltageID; - bool HasFrequencyID; - bool HasTempSenseDiode; }; - using CPUExtendedFeatures = struct tagCPUExtendedFeatures - + struct CPUExtendedFeatures { - bool Has3DNow; - bool Has3DNowPlus; - bool SupportsMP; - bool HasMMXPlus; - bool HasSSEMMX; - unsigned int LogicalProcessorsPerPhysical; - int APIC_ID; - CPUPowerManagement PowerManagement; }; - using CPUFeatures = struct CPUtagFeatures - + struct CPUFeatures { - bool HasFPU; - bool HasTSC; - bool HasMMX; - bool HasSSE; - bool HasSSEFP; - bool HasSSE2; - bool HasIA64; - bool HasAPIC; - bool HasCMOV; - bool HasMTRR; - bool HasACPI; - bool HasSerial; - bool HasThermal; - int CPUSpeed; - int L1CacheSize; - int L2CacheSize; - int L3CacheSize; - CPUExtendedFeatures ExtendedFeatures; }; @@ -874,7 +831,7 @@ int LoadLines(FILE* file, std::vector& lines) char buf[bufSize] = { '\0' }; while (!feof(file) && !ferror(file)) { errno = 0; - if (fgets(buf, bufSize, file) == nullptr) { + if (!fgets(buf, bufSize, file)) { if (ferror(file) && (errno == EINTR)) { clearerr(file); } @@ -900,7 +857,7 @@ int LoadLines(FILE* file, std::vector& lines) int LoadLines(const char* fileName, std::vector& lines) { FILE* file = fopen(fileName, "r"); - if (file == nullptr) { + if (!file) { return 0; } int nRead = LoadLines(file, lines); @@ -938,7 +895,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) return -1; } int i = 0; - while (fieldNames[i] != nullptr) { + while (fieldNames[i]) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -970,7 +927,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, T* values) { FILE* file = popen(command, "r"); - if (file == nullptr) { + if (!file) { return -1; } std::vector fields; @@ -980,7 +937,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames, return -1; } int i = 0; - while (fieldNames[i] != nullptr) { + while (fieldNames[i]) { int ierr = NameValue(fields, fieldNames[i], values[i]); if (ierr) { return -(i + 2); @@ -1016,7 +973,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGFPE: - oss << "Caught SIGFPE at " << (sigInfo->si_addr == nullptr ? "0x" : "") + oss << "Caught SIGFPE at " << (sigInfo->si_addr ? "" : "0x") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { # if defined(FPE_INTDIV) @@ -1064,7 +1021,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGSEGV: - oss << "Caught SIGSEGV at " << (sigInfo->si_addr == nullptr ? "0x" : "") + oss << "Caught SIGSEGV at " << (sigInfo->si_addr ? "" : "0x") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case SEGV_MAPERR: @@ -1082,7 +1039,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGBUS: - oss << "Caught SIGBUS at " << (sigInfo->si_addr == nullptr ? "0x" : "") + oss << "Caught SIGBUS at " << (sigInfo->si_addr ? "" : "0x") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case BUS_ADRALN: @@ -1122,7 +1079,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, break; case SIGILL: - oss << "Caught SIGILL at " << (sigInfo->si_addr == nullptr ? "0x" : "") + oss << "Caught SIGILL at " << (sigInfo->si_addr ? "" : "0x") << sigInfo->si_addr << " "; switch (sigInfo->si_code) { case ILL_ILLOPC: @@ -1659,7 +1616,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( return -2; } - for (ifa = ifas; ifa != nullptr; ifa = ifa->ifa_next) { + for (ifa = ifas; ifa; 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)) && @@ -3443,18 +3400,19 @@ bool SystemInformationImplementation::RetrieveInformationFromCpuInfoFile() FILE* fd = fopen("/proc/cpuinfo", "r"); if (!fd) { - std::cout << "Problem opening /proc/cpuinfo" << std::endl; + std::cerr << "Problem opening /proc/cpuinfo\n"; return false; } size_t fileSize = 0; - while (!feof(fd)) { - buffer += static_cast(fgetc(fd)); + int fc; + while ((fc = fgetc(fd)) != EOF) { + buffer += static_cast(fc); fileSize++; } fclose(fd); if (fileSize < 2) { - std::cout << "No data in /proc/cpuinfo" << std::endl; + std::cerr << "No data in /proc/cpuinfo\n"; return false; } buffer.resize(fileSize - 2); @@ -3886,7 +3844,7 @@ long long SystemInformationImplementation::GetProcMemoryUsed() std::ostringstream oss; oss << "ps -o rss= -p " << pid; FILE* file = popen(oss.str().c_str(), "r"); - if (file == nullptr) { + if (!file) { return -1; } oss.str(""); @@ -3923,8 +3881,7 @@ double SystemInformationImplementation::GetLoadAverage() return -0.0; #elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) // Old windows.h headers do not provide GetSystemTimes. - typedef BOOL(WINAPI * GetSystemTimesType)(LPFILETIME, LPFILETIME, - LPFILETIME); + using GetSystemTimesType = BOOL(WINAPI*)(LPFILETIME, LPFILETIME, LPFILETIME); static GetSystemTimesType pGetSystemTimes = (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"), "GetSystemTimes"); @@ -4162,7 +4119,7 @@ bool SystemInformationImplementation::QueryLinuxMemory() struct utsname unameInfo; int errorFlag = uname(&unameInfo); if (errorFlag != 0) { - std::cout << "Problem calling uname(): " << strerror(errno) << std::endl; + std::cerr << "Problem calling uname(): " << strerror(errno) << "\n"; return false; } @@ -4182,7 +4139,7 @@ bool SystemInformationImplementation::QueryLinuxMemory() FILE* fd = fopen("/proc/meminfo", "r"); if (!fd) { - std::cout << "Problem opening /proc/meminfo" << std::endl; + std::cerr << "Problem opening /proc/meminfo\n"; return false; } @@ -4221,7 +4178,7 @@ bool SystemInformationImplementation::QueryLinuxMemory() this->TotalVirtualMemory = value[mSwapTotal] / 1024; this->AvailableVirtualMemory = value[mSwapFree] / 1024; } else { - std::cout << "Problem parsing /proc/meminfo" << std::endl; + std::cerr << "Problem parsing /proc/meminfo\n"; fclose(fd); return false; } @@ -4248,7 +4205,7 @@ bool SystemInformationImplementation::QueryLinuxMemory() this->AvailablePhysicalMemory = (ap + buffersMem + cachedMem) >> 10 >> 10; } else { - std::cout << "Problem parsing /proc/meminfo" << std::endl; + std::cerr << "Problem parsing /proc/meminfo\n"; fclose(fd); return false; } @@ -4265,7 +4222,7 @@ bool SystemInformationImplementation::QueryCygwinMemory() { #ifdef __CYGWIN__ // _SC_PAGE_SIZE does return the mmap() granularity on Cygwin, - // see http://cygwin.com/ml/cygwin/2006-06/msg00350.html + // see https://sourceware.org/legacy-ml/cygwin/2006-06/msg00350.html // Therefore just use 4096 as the page size of Windows. long m = sysconf(_SC_PHYS_PAGES); if (m < 0) { @@ -4469,11 +4426,11 @@ void SystemInformationImplementation::CPUCountWindows() this->NumberOfPhysicalCPU = 0; this->NumberOfLogicalCPU = 0; - typedef BOOL(WINAPI * GetLogicalProcessorInformationType)( - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); + using GetLogicalProcessorInformationType = + BOOL(WINAPI*)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); static GetLogicalProcessorInformationType pGetLogicalProcessorInformation = - (GetLogicalProcessorInformationType)GetProcAddress( - GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation"); + reinterpret_cast(GetProcAddress( + GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation")); if (!pGetLogicalProcessorInformation) { // Fallback to approximate implementation on ancient Windows versions. @@ -4499,10 +4456,7 @@ void SystemInformationImplementation::CPUCountWindows() (void)rc; // Silence unused variable warning } - typedef std::vector::iterator - pinfoIt_t; - for (pinfoIt_t it = ProcInfo.begin(); it != ProcInfo.end(); ++it) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION PInfo = *it; + for (SYSTEM_LOGICAL_PROCESSOR_INFORMATION const& PInfo : ProcInfo) { if (PInfo.Relationship != RelationProcessorCore) { continue; } @@ -4646,7 +4600,7 @@ bool SystemInformationImplementation::ParseSysCtl() err = sysctlbyname("hw.machine", &tempBuff, &len, nullptr, 0); if (err == 0) { std::string machineBuf(tempBuff); - if (machineBuf.find_first_of("Power") != std::string::npos) { + if (machineBuf.find("Power") != std::string::npos) { this->ChipID.Vendor = "IBM"; err = kw_sysctlbyname_int32("hw.cputype", &tempInt32); @@ -4660,10 +4614,15 @@ bool SystemInformationImplementation::ParseSysCtl() } this->FindManufacturer(); - } else if (machineBuf.find_first_of("arm64") != std::string::npos) { + } else if (machineBuf.find("arm64") != std::string::npos) { this->ChipID.Vendor = "Apple"; this->FindManufacturer(); + + err = kw_sysctlbyname_int32("hw.optional.floatingpoint", &tempInt32); + if (err == 0) { + this->Features.HasFPU = static_cast(tempInt32); + } } } } else { @@ -4800,7 +4759,7 @@ std::string SystemInformationImplementation::ExtractValueFromSysCtl( std::string SystemInformationImplementation::RunProcess( std::vector args) { - std::string buffer; + std::string out; // Run the application kwsysProcess* gp = kwsysProcess_New(); @@ -4819,7 +4778,10 @@ std::string SystemInformationImplementation::RunProcess( (pipe == kwsysProcess_Pipe_STDOUT || pipe == kwsysProcess_Pipe_STDERR))) // wait for 1s { - buffer.append(data, length); + // Keep stdout, ignore stderr. + if (pipe == kwsysProcess_Pipe_STDOUT) { + out.append(data, length); + } } kwsysProcess_WaitForExit(gp, nullptr); @@ -4849,7 +4811,7 @@ std::string SystemInformationImplementation::RunProcess( if (result) { std::cerr << "Error " << args[0] << " returned :" << result << "\n"; } - return buffer; + return out; } std::string SystemInformationImplementation::ParseValueFromKStat( @@ -4890,7 +4852,7 @@ std::string SystemInformationImplementation::ParseValueFromKStat( args.reserve(3 + args_string.size()); args.push_back("kstat"); args.push_back("-p"); - for (auto& i : args_string) { + for (const auto& i : args_string) { args.push_back(i.c_str()); } args.push_back(nullptr); @@ -5459,7 +5421,7 @@ bool SystemInformationImplementation::QueryOSInformation() this->OSVersion = operatingSystem; } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { // Windows XP and .NET server. - typedef BOOL(CALLBACK * LPFNPROC)(HANDLE, BOOL*); + using LPFNPROC = BOOL(CALLBACK*)(HANDLE, BOOL*); HINSTANCE hKernelDLL; LPFNPROC DLLProc; diff --git a/SystemTools.cxx b/SystemTools.cxx index 3bb78696c2..5b579004c6 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -59,9 +59,6 @@ #include #include -#ifdef __QNX__ -# include /* for malloc/free on QNX */ -#endif #include #include #include @@ -268,7 +265,7 @@ static inline char* realpath(const char* path, char* resolved_path) snprintf(resolved_path, maxlen, "%s", path); BPath normalized(resolved_path, nullptr, true); const char* resolved = normalized.Path(); - if (resolved != nullptr) // nullptr == No such file. + if (resolved) // nullptr == No such file. { if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) { return resolved_path; @@ -338,10 +335,9 @@ inline void Realpath(const std::string& path, std::string& resolved_path, std::string* errorMessage = nullptr) { std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path); - wchar_t* ptemp; wchar_t fullpath[MAX_PATH]; DWORD bufferLen = GetFullPathNameW( - tmp.c_str(), sizeof(fullpath) / sizeof(fullpath[0]), fullpath, &ptemp); + tmp.c_str(), sizeof(fullpath) / sizeof(fullpath[0]), fullpath, nullptr); if (bufferLen < sizeof(fullpath) / sizeof(fullpath[0])) { resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath); KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path); @@ -412,18 +408,6 @@ inline void Realpath(const std::string& path, std::string& resolved_path, } #endif -#if !defined(_WIN32) && defined(__COMO__) -// Hack for como strict mode to avoid defining _SVID_SOURCE or _BSD_SOURCE. -extern "C" { -extern FILE* popen(__const char* __command, __const char* __modes) __THROW; -extern int pclose(FILE* __stream) __THROW; -extern char* realpath(__const char* __restrict __name, - char* __restrict __resolved) __THROW; -extern char* strdup(__const char* __s) __THROW; -extern int putenv(char* __string) __THROW; -} -#endif - namespace KWSYS_NAMESPACE { double SystemTools::GetTime() @@ -506,75 +490,17 @@ class kwsysEnvSet : public std::set } }; -#ifdef _WIN32 -# if defined(_WIN64) -static constexpr size_t FNV_OFFSET_BASIS = 14695981039346656037ULL; -static constexpr size_t FNV_PRIME = 1099511628211ULL; -# else -static constexpr size_t FNV_OFFSET_BASIS = 2166136261U; -static constexpr size_t FNV_PRIME = 16777619U; -# endif - -// Case insensitive Fnv1a hash -struct SystemToolsPathCaseHash -{ - size_t operator()(std::string const& path) const - { - size_t hash = FNV_OFFSET_BASIS; - for (auto c : path) { - hash ^= static_cast(std::tolower(c)); - hash *= FNV_PRIME; - } - - return hash; - } -}; - -struct SystemToolsPathCaseEqual -{ - bool operator()(std::string const& l, std::string const& r) const - { -# ifdef _MSC_VER - return _stricmp(l.c_str(), r.c_str()) == 0; -# elif defined(__GNUC__) - return strcasecmp(l.c_str(), r.c_str()) == 0; -# else - return SystemTools::Strucmp(l.c_str(), r.c_str()) == 0; -# endif - } -}; -#endif - /** * SystemTools static variables singleton class. */ class SystemToolsStatic { public: - using StringMap = std::map; -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP - /** - * Path translation table from dir to refdir - * Each time 'dir' will be found it will be replace by 'refdir' - */ - StringMap TranslationMap; -#endif #ifdef _WIN32 - static std::string GetCasePathName(std::string const& pathIn, - bool const cache); - static std::string GetActualCaseForPathCached(std::string const& path); + static std::string GetCasePathName(std::string const& pathIn); static const char* GetEnvBuffered(const char* key); - std::unordered_map - FindFileMap; - std::unordered_map - PathCaseMap; std::map EnvMap; #endif -#ifdef __CYGWIN__ - StringMap Cyg2Win32Map; -#endif /** * Actual implementation of ReplaceString. @@ -601,8 +527,7 @@ class SystemToolsStatic static SystemToolsStatic* SystemToolsStatics; #ifdef _WIN32 -std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn, - bool const cache) +std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn) { std::string casePath; @@ -655,30 +580,15 @@ std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn, std::string test_str = casePath; test_str += path_components[idx]; - bool found_in_cache = false; - if (cache) { - auto const it = SystemToolsStatics->FindFileMap.find(test_str); - if (it != SystemToolsStatics->FindFileMap.end()) { - path_components[idx] = it->second; - found_in_cache = true; - } - } - - if (!found_in_cache) { - WIN32_FIND_DATAW findData; - HANDLE hFind = - ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData); - if (INVALID_HANDLE_VALUE != hFind) { - auto case_file_name = Encoding::ToNarrow(findData.cFileName); - if (cache) { - SystemToolsStatics->FindFileMap.emplace(test_str, - case_file_name); - } - path_components[idx] = std::move(case_file_name); - ::FindClose(hFind); - } else { - converting = false; - } + WIN32_FIND_DATAW findData; + HANDLE hFind = + ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData); + if (INVALID_HANDLE_VALUE != hFind) { + auto case_file_name = Encoding::ToNarrow(findData.cFileName); + path_components[idx] = std::move(case_file_name); + ::FindClose(hFind); + } else { + converting = false; } } } @@ -687,21 +597,6 @@ std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn, } return casePath; } - -std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p) -{ - std::string casePath; - - auto it = SystemToolsStatics->PathCaseMap.find(p); - if (it != SystemToolsStatics->PathCaseMap.end()) { - casePath = it->second; - } else { - casePath = SystemToolsStatic::GetCasePathName(p, true); - SystemToolsStatics->PathCaseMap.emplace(p, casePath); - } - - return casePath; -} #endif // adds the elements of the env variable path to the arg passed in @@ -777,12 +672,16 @@ const char* SystemTools::GetEnv(const std::string& key) bool SystemTools::GetEnv(const char* key, std::string& result) { #if defined(_WIN32) - const std::wstring wkey = Encoding::ToWide(key); - const wchar_t* wv = _wgetenv(wkey.c_str()); - if (wv) { - result = Encoding::ToNarrow(wv); - return true; + auto wide_key = Encoding::ToWide(key); + auto result_size = GetEnvironmentVariableW(wide_key.data(), nullptr, 0); + if (result_size <= 0) { + return false; } + std::wstring wide_result; + wide_result.resize(result_size - 1); + GetEnvironmentVariableW(wide_key.data(), &wide_result[0], result_size); + result = Encoding::ToNarrow(wide_result); + return true; #else const char* v = getenv(key); if (v) { @@ -806,7 +705,7 @@ bool SystemTools::HasEnv(const char* key) #else const char* v = getenv(key); #endif - return v != nullptr; + return v; } bool SystemTools::HasEnv(const std::string& key) @@ -832,25 +731,14 @@ static int kwsysUnPutEnv(const std::string& env) #elif defined(__CYGWIN__) || defined(__GLIBC__) /* putenv("A") removes A from the environment. It must not put the memory in the environment because it does not have any "=" syntax. */ + static int kwsysUnPutEnv(const std::string& env) { int err = 0; - size_t pos = env.find('='); - size_t const len = pos == std::string::npos ? env.size() : pos; - size_t const sz = len + 1; - char local_buf[256]; - char* buf = sz > sizeof(local_buf) ? (char*)malloc(sz) : local_buf; - if (!buf) { - return -1; - } - strncpy(buf, env.c_str(), len); - buf[len] = 0; - if (putenv(buf) < 0 && errno != EINVAL) { + std::string buf = env.substr(0, env.find('=')); + if (putenv(&buf[0]) < 0 && errno != EINVAL) { err = errno; } - if (buf != local_buf) { - free(buf); - } if (err) { errno = err; return -1; @@ -1175,7 +1063,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 == nullptr) { + if (!wow64p) { return mode; } @@ -1364,6 +1252,75 @@ bool SystemTools::DeleteRegistryValue(const std::string&, KeyWOW64) } #endif +#ifdef _WIN32 +SystemTools::WindowsFileId::WindowsFileId(unsigned long volumeSerialNumber, + unsigned long fileIndexHigh, + unsigned long fileIndexLow) + : m_volumeSerialNumber(volumeSerialNumber) + , m_fileIndexHigh(fileIndexHigh) + , m_fileIndexLow(fileIndexLow) +{ +} + +bool SystemTools::WindowsFileId::operator==(const WindowsFileId& o) const +{ + return (m_volumeSerialNumber == o.m_volumeSerialNumber && + m_fileIndexHigh == o.m_fileIndexHigh && + m_fileIndexLow == o.m_fileIndexLow); +} + +bool SystemTools::WindowsFileId::operator!=(const WindowsFileId& o) const +{ + return !(*this == o); +} +#else +SystemTools::UnixFileId::UnixFileId(dev_t volumeSerialNumber, + ino_t fileSerialNumber, off_t fileSize) + : m_volumeSerialNumber(volumeSerialNumber) + , m_fileSerialNumber(fileSerialNumber) + , m_fileSize(fileSize) +{ +} + +bool SystemTools::UnixFileId::operator==(const UnixFileId& o) const +{ + return (m_volumeSerialNumber == o.m_volumeSerialNumber && + m_fileSerialNumber == o.m_fileSerialNumber && + m_fileSize == o.m_fileSize); +} + +bool SystemTools::UnixFileId::operator!=(const UnixFileId& o) const +{ + return !(*this == o); +} +#endif + +bool SystemTools::GetFileId(const std::string& file, FileId& id) +{ +#ifdef _WIN32 + HANDLE hFile = + CreateFileW(Encoding::ToWide(file).c_str(), GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (hFile != INVALID_HANDLE_VALUE) { + BY_HANDLE_FILE_INFORMATION fiBuf; + GetFileInformationByHandle(hFile, &fiBuf); + CloseHandle(hFile); + id = FileId(fiBuf.dwVolumeSerialNumber, fiBuf.nFileIndexHigh, + fiBuf.nFileIndexLow); + return true; + } else { + return false; + } +#else + struct stat fileStat; + if (stat(file.c_str(), &fileStat) == 0) { + id = FileId(fileStat.st_dev, fileStat.st_ino, fileStat.st_size); + return true; + } + return false; +#endif +} + bool SystemTools::SameFile(const std::string& file1, const std::string& file2) { #ifdef _WIN32 @@ -2536,8 +2493,12 @@ SystemTools::CopyStatus SystemTools::CloneFileContent( // NOTE: we cannot use `clonefile` as the {a,c,m}time for the file needs to // be updated by `copy_file_if_different` and `copy_file`. + // These flags are meant to be COPYFILE_METADATA | COPYFILE_CLONE, but CLONE + // forces COPYFILE_NOFOLLOW_SRC and that violates the invariant that this + // should result in a file. if (copyfile(source.c_str(), destination.c_str(), nullptr, - COPYFILE_METADATA | COPYFILE_CLONE) < 0) { + COPYFILE_METADATA | COPYFILE_EXCL | COPYFILE_STAT | + COPYFILE_XATTR | COPYFILE_DATA) < 0) { return CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath }; } # if KWSYS_CXX_HAS_UTIMENSAT @@ -2802,14 +2763,14 @@ Status SystemTools::RemoveFile(std::string const& source) Status SystemTools::RemoveADirectory(std::string const& source) { - // Add write permission to the directory so we can modify its - // content to remove files and directories from it. + // Add read and write permission to the directory so we can read + // and modify its content to remove files and directories from it. mode_t mode = 0; if (SystemTools::GetPermissions(source, mode)) { #if defined(_WIN32) && !defined(__CYGWIN__) - mode |= S_IWRITE; + mode |= S_IREAD | S_IWRITE; #else - mode |= S_IWUSR; + mode |= S_IRUSR | S_IWUSR; #endif SystemTools::SetPermissions(source, mode); } @@ -2875,9 +2836,8 @@ std::string SystemToolsStatic::FindName( path.reserve(path.size() + userPaths.size()); path.insert(path.end(), userPaths.begin(), userPaths.end()); // now look for the file - std::string tryPath; for (std::string const& p : path) { - tryPath = p; + std::string tryPath = p; if (tryPath.empty() || tryPath.back() != '/') { tryPath += '/'; } @@ -2946,8 +2906,6 @@ std::string SystemTools::FindProgram(const std::string& name, const std::vector& userPaths, bool no_system_path) { - std::string tryPath; - #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) std::vector extensions; // check to see if the name already has a .xxx at @@ -2959,7 +2917,7 @@ std::string SystemTools::FindProgram(const std::string& name, // first try with extensions if the os supports them for (std::string const& ext : extensions) { - tryPath = name; + std::string tryPath = name; tryPath += ext; if (SystemTools::FileIsExecutable(tryPath)) { return SystemTools::CollapseFullPath(tryPath); @@ -2996,7 +2954,7 @@ std::string SystemTools::FindProgram(const std::string& name, #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) // first try with extensions for (std::string const& ext : extensions) { - tryPath = p; + std::string tryPath = p; tryPath += name; tryPath += ext; if (SystemTools::FileIsExecutable(tryPath)) { @@ -3005,7 +2963,7 @@ std::string SystemTools::FindProgram(const std::string& name, } #endif // now try it without them - tryPath = p; + std::string tryPath = p; tryPath += name; if (SystemTools::FileIsExecutable(tryPath)) { return SystemTools::CollapseFullPath(tryPath); @@ -3160,16 +3118,13 @@ bool SystemTools::FileIsDirectory(const std::string& inName) #if defined(_WIN32) DWORD attr = GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str()); - if (attr != INVALID_FILE_ATTRIBUTES) { - return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; + return (attr != INVALID_FILE_ATTRIBUTES) && + (attr & FILE_ATTRIBUTE_DIRECTORY); #else struct stat fs; - if (stat(name, &fs) == 0) { - return S_ISDIR(fs.st_mode); + + return (stat(name, &fs) == 0) && S_ISDIR(fs.st_mode); #endif - } else { - return false; - } } bool SystemTools::FileIsExecutable(const std::string& inName) @@ -3234,11 +3189,7 @@ bool SystemTools::FileIsSymlink(const std::string& name) return FileIsSymlinkWithAttr(path, GetFileAttributesW(path.c_str())); #else struct stat fs; - if (lstat(name.c_str(), &fs) == 0) { - return S_ISLNK(fs.st_mode); - } else { - return false; - } + return (lstat(name.c_str(), &fs) == 0) && S_ISLNK(fs.st_mode); #endif } @@ -3256,11 +3207,7 @@ bool SystemTools::FileIsFIFO(const std::string& name) return type == FILE_TYPE_PIPE; #else struct stat fs; - if (lstat(name.c_str(), &fs) == 0) { - return S_ISFIFO(fs.st_mode); - } else { - return false; - } + return (lstat(name.c_str(), &fs) == 0) && S_ISFIFO(fs.st_mode); #endif } @@ -3347,7 +3294,7 @@ Status SystemTools::ReadSymlink(std::string const& newName, // terminated by an empty string (0-0). We need the third string. size_t destLen; substituteNameData = GetAppExecLink(data, destLen); - if (substituteNameData == nullptr || destLen == 0) { + if (!substituteNameData || destLen == 0) { return Status::Windows(ERROR_SYMLINK_NOT_SUPPORTED); } substituteNameLength = static_cast(destLen); @@ -3356,6 +3303,14 @@ Status SystemTools::ReadSymlink(std::string const& newName, } std::wstring substituteName(substituteNameData, substituteNameLength); origName = Encoding::ToNarrow(substituteName); + // Symbolic links to absolute paths may use a NT Object Path prefix. + // If the path begins with "\??\UNC\", replace it with "\\". + // Otherwise, if the path begins with "\??\", remove the prefix. + if (origName.compare(0, 8, "\\??\\UNC\\") == 0) { + origName.erase(1, 6); + } else if (origName.compare(0, 4, "\\??\\") == 0) { + origName.erase(0, 4); + } #else char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1]; int count = static_cast( @@ -3450,72 +3405,6 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut, return true; } -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP -void SystemTools::AddTranslationPath(const std::string& a, - const std::string& b) -{ - std::string path_a = a; - std::string path_b = b; - SystemTools::ConvertToUnixSlashes(path_a); - SystemTools::ConvertToUnixSlashes(path_b); - // First check this is a directory path, since we don't want the table to - // grow too fat - if (SystemTools::FileIsDirectory(path_a)) { - // Make sure the path is a full path and does not contain no '..' - // Ken--the following code is incorrect. .. can be in a valid path - // for example /home/martink/MyHubba...Hubba/Src - if (SystemTools::FileIsFullPath(path_b) && - path_b.find("..") == std::string::npos) { - // Before inserting make sure path ends with '/' - if (!path_a.empty() && path_a.back() != '/') { - path_a += '/'; - } - if (!path_b.empty() && path_b.back() != '/') { - path_b += '/'; - } - if (!(path_a == path_b)) { - SystemToolsStatics->TranslationMap.insert( - SystemToolsStatic::StringMap::value_type(std::move(path_a), - std::move(path_b))); - } - } - } -} - -void SystemTools::AddKeepPath(const std::string& dir) -{ - std::string cdir; - Realpath(SystemTools::CollapseFullPath(dir), cdir); - SystemTools::AddTranslationPath(cdir, dir); -} - -void SystemTools::CheckTranslationPath(std::string& path) -{ - // Do not translate paths that are too short to have meaningful - // translations. - if (path.size() < 2) { - return; - } - - // Always add a trailing slash before translation. It does not - // matter if this adds an extra slash, but we do not want to - // translate part of a directory (like the foo part of foo-dir). - path += '/'; - - // In case a file was specified we still have to go through this: - // Now convert any path found in the table back to the one desired: - for (auto const& pair : SystemToolsStatics->TranslationMap) { - // We need to check of the path is a substring of the other path - if (path.compare(0, pair.first.size(), pair.first) == 0) { - path = path.replace(0, pair.first.size(), pair.second); - } - } - - // Remove the trailing slash we added before. - path.pop_back(); -} -#endif - static void SystemToolsAppendComponents( std::vector& out_components, std::vector::iterator first, @@ -3578,25 +3467,7 @@ std::string CollapseFullPathImpl(std::string const& in_path, // Transform the path back to a string. std::string newPath = SystemTools::JoinPath(out_components); -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP - // Update the translation table with this potentially new path. I am not - // sure why this line is here, it seems really questionable, but yet I - // would put good money that if I remove it something will break, basically - // from what I can see it created a mapping from the collapsed path, to be - // replaced by the input path, which almost completely does the opposite of - // this function, the only thing preventing this from happening a lot is - // that if the in_path has a .. in it, then it is not added to the - // translation table. So for most calls this either does nothing due to the - // .. or it adds a translation between identical paths as nothing was - // collapsed, so I am going to try to comment it out, and see what hits the - // fan, hopefully quickly. - // Commented out line below: - // SystemTools::AddTranslationPath(newPath, in_path); - - SystemTools::CheckTranslationPath(newPath); -#endif #ifdef _WIN32 - newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath); SystemTools::ConvertToUnixSlashes(newPath); #endif // Return the reconstructed path. @@ -3705,7 +3576,7 @@ std::string SystemTools::RelativePath(const std::string& local, std::string SystemTools::GetActualCaseForPath(const std::string& p) { #ifdef _WIN32 - return SystemToolsStatic::GetCasePathName(p, false); + return SystemToolsStatic::GetCasePathName(p); #else return p; #endif @@ -4897,7 +4768,7 @@ SystemToolsManager::~SystemToolsManager() #if defined(__VMS) // On VMS we configure the run time C library to be more UNIX like. -// http://h71000.www7.hp.com/doc/732final/5763/5763pro_004.html +// https://h71000.www7.hp.com/doc/732final/5763/5763pro_004.html extern "C" int decc$feature_get_index(char* name); extern "C" int decc$feature_set_value(int index, int mode, int value); static int SetVMSFeature(char* name, int value) @@ -4917,51 +4788,6 @@ void SystemTools::ClassInitialize() // Create statics singleton instance SystemToolsStatics = new SystemToolsStatic; - -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP -// Add some special translation paths for unix. These are not added -// for windows because drive letters need to be maintained. Also, -// there are not sym-links and mount points on windows anyway. -# if !defined(_WIN32) || defined(__CYGWIN__) - // The tmp path is frequently a logical path so always keep it: - SystemTools::AddKeepPath("/tmp/"); - - // If the current working directory is a logical path then keep the - // logical name. - std::string pwd_str; - if (SystemTools::GetEnv("PWD", pwd_str)) { - char buf[2048]; - if (const char* cwd = Getcwd(buf, 2048)) { - // The current working directory may be a logical path. Find - // the shortest logical path that still produces the correct - // physical path. - std::string cwd_changed; - std::string pwd_changed; - - // Test progressively shorter logical-to-physical mappings. - std::string cwd_str = cwd; - std::string pwd_path; - Realpath(pwd_str, pwd_path); - while (cwd_str == pwd_path && cwd_str != pwd_str) { - // The current pair of paths is a working logical mapping. - cwd_changed = cwd_str; - pwd_changed = pwd_str; - - // Strip off one directory level and see if the logical - // mapping still works. - pwd_str = SystemTools::GetFilenamePath(pwd_str); - cwd_str = SystemTools::GetFilenamePath(cwd_str); - Realpath(pwd_str, pwd_path); - } - - // Add the translation to keep the logical path name. - if (!cwd_changed.empty() && !pwd_changed.empty()) { - SystemTools::AddTranslationPath(cwd_changed, pwd_changed); - } - } - } -# endif -#endif } void SystemTools::ClassFinalize() diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index 729928e6f3..03fa3bced0 100644 --- a/SystemTools.hxx.in +++ b/SystemTools.hxx.in @@ -616,6 +616,52 @@ public: static CopyStatus CloneFileContent(std::string const& source, std::string const& destination); + /** + * Object encapsulating a unique identifier for a file + * or directory + */ +#ifdef _WIN32 + class WindowsFileId + { + public: + WindowsFileId() = default; + WindowsFileId(unsigned long volumeSerialNumber, + unsigned long fileIndexHigh, unsigned long fileIndexLow); + + bool operator==(const WindowsFileId& o) const; + bool operator!=(const WindowsFileId& o) const; + + private: + unsigned long m_volumeSerialNumber; + unsigned long m_fileIndexHigh; + unsigned long m_fileIndexLow; + }; + using FileId = WindowsFileId; +#else + class UnixFileId + { + public: + UnixFileId() = default; + UnixFileId(dev_t volumeSerialNumber, ino_t fileSerialNumber, + off_t fileSize); + + bool operator==(const UnixFileId& o) const; + bool operator!=(const UnixFileId& o) const; + + private: + dev_t m_volumeSerialNumber; + ino_t m_fileSerialNumber; + off_t m_fileSize; + }; + using FileId = UnixFileId; +#endif + + /** + * Outputs a FileId for the given file or directory. + * Returns true on success, false on failure + */ + static bool GetFileId(const std::string& file, FileId& id); + /** * Return true if the two files are the same file */ @@ -938,25 +984,6 @@ public: */ static int GetTerminalWidth(); -#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP - /** - * Add an entry in the path translation table. - */ - static void AddTranslationPath(const std::string& dir, - const std::string& refdir); - - /** - * If dir is different after CollapseFullPath is called, - * Then insert it into the path translation table - */ - static void AddKeepPath(const std::string& dir); - - /** - * Update path by going through the Path Translation table; - */ - static void CheckTranslationPath(std::string& path); -#endif - /** * Delay the execution for a specified amount of time specified * in milliseconds @@ -1006,14 +1033,7 @@ public: static std::string DecodeURL(const std::string& url); private: - /** - * Allocate the stl map that serve as the Path Translation table. - */ static void ClassInitialize(); - - /** - * Deallocate the stl map that serve as the Path Translation table. - */ static void ClassFinalize(); /** diff --git a/Terminal.c b/Terminal.c index 39081a7527..eb6e01b5ec 100644 --- a/Terminal.c +++ b/Terminal.c @@ -168,7 +168,7 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm", static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, int default_tty) { - /* Force color according to http://bixense.com/clicolors/ convention. */ + /* Force color according to https://bixense.com/clicolors/ convention. */ { const char* clicolor_force = getenv("CLICOLOR_FORCE"); if (clicolor_force && *clicolor_force && @@ -177,7 +177,7 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, } } - /* Disable color according to http://bixense.com/clicolors/ convention. */ + /* Disable color according to https://bixense.com/clicolors/ convention. */ { const char* clicolor = getenv("CLICOLOR"); if (clicolor && strcmp(clicolor, "0") == 0) { diff --git a/testConsoleBuf.cxx b/testConsoleBuf.cxx index f9b826d215..64c61e2ff1 100644 --- a/testConsoleBuf.cxx +++ b/testConsoleBuf.cxx @@ -476,6 +476,22 @@ static int testFile() # define _WIN32_WINNT_VISTA 0x0600 # endif +static bool consoleIsConhost() +{ + wchar_t consoleClassNameBuf[64]; + int const consoleClassNameLen = GetClassNameW( + GetConsoleWindow(), &consoleClassNameBuf[0], sizeof(consoleClassNameBuf)); + // Windows Console Host: ConsoleWindowClass + // Windows Terminal / ConPTY: PseudoConsoleWindow (undocumented) + return (consoleClassNameLen > 0 && + wcscmp(consoleClassNameBuf, L"ConsoleWindowClass") == 0); +} + +static bool charIsNUL(wchar_t c) +{ + return c == 0; +} + static int testConsole() { int didFail = 1; @@ -691,7 +707,15 @@ static int testConsole() throw std::runtime_error("ReadConsoleOutputCharacter failed!"); } std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString); - std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); + if (consoleIsConhost()) { + // Windows Console Host converts NUL bytes to spaces. + std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); + } else { + // Windows Terminal / ConPTY removes NUL bytes. + wideTestString.erase(std::remove_if(wideTestString.begin(), + wideTestString.end(), charIsNUL), + wideTestString.end()); + } std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString); if (memcmp(outputBuffer, wideTestString.c_str(), diff --git a/testSystemTools.cxx b/testSystemTools.cxx index 8afcb68273..9275043141 100644 --- a/testSystemTools.cxx +++ b/testSystemTools.cxx @@ -1148,12 +1148,12 @@ static bool CheckCopyFileIfDifferent() static bool CheckURLParsing() { bool ret = true; - std::string url = "http://user:pw@hostname:42/full/url.com"; + std::string url = "https://user:pw@hostname:42/full/url.com"; std::string protocol, username, password, hostname, dataport, database; kwsys::SystemTools::ParseURL(url, protocol, username, password, hostname, dataport, database); - if (protocol != "http" || username != "user" || password != "pw" || + if (protocol != "https" || username != "user" || password != "pw" || hostname != "hostname" || dataport != "42" || database != "full/url.com") { std::cerr << "Incorrect URL parsing" << std::endl;