summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys')
-rw-r--r--Source/kwsys/CMakeLists.txt29
-rw-r--r--Source/kwsys/CommandLineArguments.cxx25
-rw-r--r--Source/kwsys/Configure.h.in3
-rw-r--r--Source/kwsys/Configure.hxx.in26
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in2
-rw-r--r--Source/kwsys/DynamicLoader.cxx17
-rw-r--r--Source/kwsys/DynamicLoader.hxx.in4
-rw-r--r--Source/kwsys/Process.h.in10
-rw-r--r--Source/kwsys/ProcessUNIX.c33
-rw-r--r--Source/kwsys/ProcessWin32.c20
-rw-r--r--Source/kwsys/RegularExpression.cxx189
-rw-r--r--Source/kwsys/RegularExpression.hxx.in231
-rw-r--r--Source/kwsys/SystemInformation.cxx4
-rw-r--r--Source/kwsys/SystemInformation.hxx.in2
-rw-r--r--Source/kwsys/SystemTools.cxx76
-rw-r--r--Source/kwsys/SystemTools.hxx.in24
-rw-r--r--Source/kwsys/hash_map.hxx.in2
-rw-r--r--Source/kwsys/hash_set.hxx.in2
-rw-r--r--Source/kwsys/hashtable.hxx.in13
-rw-r--r--Source/kwsys/kwsysPlatformTestsC.c15
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx2
-rw-r--r--Source/kwsys/testConfigure.cxx30
-rw-r--r--Source/kwsys/testEncoding.cxx5
-rw-r--r--Source/kwsys/testProcess.c32
-rw-r--r--Source/kwsys/testSystemTools.cxx45
25 files changed, 565 insertions, 276 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 21568bb..351e38d 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -445,8 +445,13 @@ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
"Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
"Checking whether C compiler has ssize_t in unistd.h" DIRECT)
+IF(KWSYS_USE_Process)
+ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+ "Checking whether C compiler has clock_gettime" DIRECT)
+ENDIF()
+
SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
- COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}"
+ COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}"
)
IF(DEFINED KWSYS_PROCESS_USE_SELECT)
@@ -700,9 +705,13 @@ ENDIF()
# selected components. Initialize with required components.
SET(KWSYS_CLASSES)
SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String
- hashtable hash_fun hash_map hash_set
- )
+SET(KWSYS_HXX_FILES Configure String)
+
+IF(NOT CMake_SOURCE_DIR)
+ SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
+ hashtable hash_fun hash_map hash_set
+ )
+ENDIF()
# Add selected C++ classes.
SET(cppclasses
@@ -1022,12 +1031,13 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
ENDFOREACH()
# C++ tests
- IF(NOT WATCOM)
+ IF(NOT WATCOM AND NOT CMake_SOURCE_DIR)
SET(KWSYS_CXX_TESTS
testHashSTL
)
ENDIF()
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testConfigure
testSystemTools
testCommandLineArguments
testCommandLineArguments1
@@ -1142,17 +1152,22 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
ENDFOREACH()
+ SET(testProcess_COMPILE_FLAGS "")
# Some Apple compilers produce bad optimizations in this source.
IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
- SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0)
+ SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL" AND
NOT (CMAKE_SYSTEM MATCHES "Linux.*ppc64le" AND
NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1"))
# Tell IBM XL not to warn about our test infinite loop
# v13.1.1 and newer on Linux ppc64le is clang based and does not accept
# the -qsuppress option
- SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS -qsuppress=1500-010)
+ SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
+ ENDIF()
+ IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
+ SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
ENDIF()
+ SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
# Test SharedForward
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 5613bd7..5792da9 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -529,10 +529,7 @@ void CommandLineArguments::GenerateHelp()
}
}
- // Create format for that string
- char format[80];
- sprintf(format, " %%-%us ", static_cast<unsigned int>(maxlen));
-
+ CommandLineArguments::Internal::String::size_type maxstrlen = maxlen;
maxlen += 4; // For the space before and after the option
// Print help for each option
@@ -540,27 +537,24 @@ void CommandLineArguments::GenerateHelp()
CommandLineArguments::Internal::SetOfStrings::iterator sit;
for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) {
str << std::endl;
- char argument[100];
- sprintf(argument, "%s", sit->c_str());
+ std::string argument = *sit;
switch (this->Internals->Callbacks[*sit].ArgumentType) {
case CommandLineArguments::NO_ARGUMENT:
break;
case CommandLineArguments::CONCAT_ARGUMENT:
- strcat(argument, "opt");
+ argument += "opt";
break;
case CommandLineArguments::SPACE_ARGUMENT:
- strcat(argument, " opt");
+ argument += " opt";
break;
case CommandLineArguments::EQUAL_ARGUMENT:
- strcat(argument, "=opt");
+ argument += "=opt";
break;
case CommandLineArguments::MULTI_ARGUMENT:
- strcat(argument, " opt opt ...");
+ argument += " opt opt ...";
break;
}
- char buffer[80];
- sprintf(buffer, format, argument);
- str << buffer;
+ str << " " << argument.substr(0, maxstrlen) << " ";
}
const char* ptr = this->Internals->Callbacks[mpit->first].Help;
size_t len = strlen(ptr);
@@ -649,10 +643,7 @@ void CommandLineArguments::PopulateVariable(double* variable,
void CommandLineArguments::PopulateVariable(char** variable,
const std::string& value)
{
- if (*variable) {
- delete[] * variable;
- *variable = 0;
- }
+ delete[] * variable;
*variable = new char[value.size() + 1];
strcpy(*variable, value.c_str());
}
diff --git a/Source/kwsys/Configure.h.in b/Source/kwsys/Configure.h.in
index 0afcae7..224047a 100644
--- a/Source/kwsys/Configure.h.in
+++ b/Source/kwsys/Configure.h.in
@@ -62,9 +62,6 @@
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_FILE_OFFSET_BITS)
#define _FILE_OFFSET_BITS 64
#endif
-#if 0 && (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64)
-#error "_FILE_OFFSET_BITS must be defined to at least 64"
-#endif
#endif
#endif
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 1c07a4e..1e67874 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -12,6 +12,31 @@
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
+#if defined(__SUNPRO_CC) && __SUNPRO_CC > 0x5130 && defined(__has_attribute)
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_attribute(x)
+#elif defined(__has_cpp_attribute)
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_cpp_attribute(x)
+#else
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) 0
+#endif
+
+#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH
+#if __cplusplus >= 201703L && @KWSYS_NAMESPACE@__has_cpp_attribute(fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[fallthrough]]
+#elif __cplusplus >= 201103L && \
+ @KWSYS_NAMESPACE@__has_cpp_attribute(gnu::fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[gnu::fallthrough]]
+#elif __cplusplus >= 201103L && \
+ @KWSYS_NAMESPACE@__has_cpp_attribute(clang::fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[clang::fallthrough]]
+#endif
+#endif
+#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH
+#define @KWSYS_NAMESPACE@_FALLTHROUGH static_cast<void>(0)
+#endif
+
+#undef @KWSYS_NAMESPACE@__has_cpp_attribute
+
/* If building a C++ file in kwsys itself, give the source file
access to the macros without a configured namespace. */
#if defined(KWSYS_NAMESPACE)
@@ -22,6 +47,7 @@
#define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING
#define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
+#define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH
#endif
#endif
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
index 46d65a8..cf68146 100644
--- a/Source/kwsys/ConsoleBuf.hxx.in
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -264,6 +264,7 @@ private:
if (m_isConsoleInput) {
break;
}
+ @KWSYS_NAMESPACE@_FALLTHROUGH;
case FILE_TYPE_PIPE:
m_activeInputCodepage = input_pipe_codepage;
break;
@@ -290,6 +291,7 @@ private:
if (m_isConsoleOutput) {
break;
}
+ @KWSYS_NAMESPACE@_FALLTHROUGH;
case FILE_TYPE_PIPE:
m_activeOutputCodepage = output_pipe_codepage;
break;
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index 1b4596a..664f183 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -163,17 +163,13 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
{
void* result = 0;
// Need to prepend symbols with '_' on Apple-gcc compilers
- size_t len = sym.size();
- char* rsym = new char[len + 1 + 1];
- strcpy(rsym, "_");
- strcat(rsym + 1, sym.c_str());
+ std::string rsym = '_' + sym;
- NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
+ NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str());
if (symbol) {
result = NSAddressOfSymbol(symbol);
}
- delete[] rsym;
// Hack to cast pointer-to-data to pointer-to-function.
return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}
@@ -237,17 +233,12 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
void* result;
#if defined(__BORLANDC__) || defined(__WATCOMC__)
// Need to prepend symbols with '_'
- size_t len = sym.size();
- char* rsym = new char[len + 1 + 1];
- strcpy(rsym, "_");
- strcat(rsym, sym.c_str());
+ std::string ssym = '_' + sym;
+ const char* rsym = ssym.c_str();
#else
const char* rsym = sym.c_str();
#endif
result = (void*)GetProcAddress(lib, rsym);
-#if defined(__BORLANDC__) || defined(__WATCOMC__)
- delete[] rsym;
-#endif
// Hack to cast pointer-to-data to pointer-to-function.
#ifdef __WATCOMC__
return *(DynamicLoader::SymbolPointer*)(&result);
diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in
index 7e71a45..dc34692 100644
--- a/Source/kwsys/DynamicLoader.hxx.in
+++ b/Source/kwsys/DynamicLoader.hxx.in
@@ -35,7 +35,7 @@ namespace @KWSYS_NAMESPACE@ {
* or absolute) pathname. Otherwise, the dynamic linker searches for the
* library as follows : see ld.so(8) for further details):
* Whereas this distinction does not exist on Win32. Therefore ideally you
- * should be doing full path to garantee to have a consistent way of dealing
+ * should be doing full path to guarantee to have a consistent way of dealing
* with dynamic loading of shared library.
*
* \warning the Cygwin implementation do not use the Win32 HMODULE. Put extra
@@ -72,7 +72,7 @@ public:
static LibraryHandle OpenLibrary(const std::string&);
/** Attempt to detach a dynamic library from the
- * process. A value of true is returned if it is sucessful. */
+ * process. A value of true is returned if it is successful. */
static int CloseLibrary(LibraryHandle);
/** Find the address of the symbol in the given library. */
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 237001c..daf334a 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -77,6 +77,7 @@
#define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
#define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
#define kwsysProcess_Kill kwsys_ns(Process_Kill)
+#define kwsysProcess_KillPID kwsys_ns(Process_KillPID)
#define kwsysProcess_ResetStartTime kwsys_ns(Process_ResetStartTime)
#endif
@@ -420,7 +421,7 @@ enum kwsysProcess_Pipes_e
/**
* Block until the child process terminates or the given timeout
- * expires. If no process is running, returns immediatly. The
+ * expires. If no process is running, returns immediately. The
* argument is:
*
* timeout = Specifies the maximum time this call may block. Upon
@@ -457,6 +458,13 @@ kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp);
kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
/**
+ * Same as kwsysProcess_Kill using process ID to locate process to
+ * terminate.
+ * @see kwsysProcess_Kill(kwsysProcess* cp)
+ */
+kwsysEXPORT void kwsysProcess_KillPID(unsigned long);
+
+/**
* Reset the start time of the child process to the current time.
*/
kwsysEXPORT void kwsysProcess_ResetStartTime(kwsysProcess* cp);
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 3b32ca7..718a1aa 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -359,9 +359,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
free(cp->ProcessResults);
free(cp);
}
@@ -498,11 +496,10 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
cp->WorkingDirectory = 0;
}
if (dir) {
- cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
+ cp->WorkingDirectory = strdup(dir);
if (!cp->WorkingDirectory) {
return 0;
}
- strcpy(cp->WorkingDirectory, dir);
}
return 1;
}
@@ -531,11 +528,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
*pfile = 0;
}
if (file) {
- *pfile = (char*)malloc(strlen(file) + 1);
+ *pfile = strdup(file);
if (!*pfile) {
return 0;
}
- strcpy(*pfile, file);
}
/* If we are redirecting the pipe, do not share it or use a native
@@ -1514,9 +1510,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
oldForkPIDs = cp->ForkPIDs;
cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) *
(size_t)(cp->NumberOfCommands));
- if (oldForkPIDs) {
- kwsysProcessVolatileFree(oldForkPIDs);
- }
+ kwsysProcessVolatileFree(oldForkPIDs);
if (!cp->ForkPIDs) {
return 0;
}
@@ -1524,9 +1518,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
}
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
cp->CommandExitCodes =
(int*)malloc(sizeof(int) * (size_t)(cp->NumberOfCommands));
if (!cp->CommandExitCodes) {
@@ -1938,6 +1930,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
/* Set close-on-exec flag on the pipe's end. */
if (fcntl(fout, F_SETFD, FD_CLOEXEC) < 0) {
+ close(fout);
return 0;
}
@@ -2033,7 +2026,15 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
{
kwsysProcessTime current;
kwsysProcessTimeNative current_native;
+#if KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+ struct timespec current_timespec;
+ clock_gettime(CLOCK_MONOTONIC, &current_timespec);
+
+ current_native.tv_sec = current_timespec.tv_sec;
+ current_native.tv_usec = current_timespec.tv_nsec / 1000;
+#else
gettimeofday(&current_native, 0);
+#endif
current.tv_sec = (long)current_native.tv_sec;
current.tv_usec = (long)current_native.tv_usec;
return current;
@@ -2290,6 +2291,7 @@ static void kwsysProcessChildErrorExit(int errorPipe)
char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
kwsysProcess_ssize_t result;
strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+ buffer[KWSYSPE_PIPE_BUFFER_SIZE - 1] = '\0';
/* Report the error to the parent through the special pipe. */
result = write(errorPipe, buffer, strlen(buffer));
@@ -2483,6 +2485,11 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
#define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n"
#endif
+void kwsysProcess_KillPID(unsigned long process_id)
+{
+ kwsysProcessKill((pid_t)process_id);
+}
+
static void kwsysProcessKill(pid_t process_id)
{
#if defined(__linux__) || defined(__CYGWIN__)
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 5183e3d..82fdc74 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -523,9 +523,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
free(cp->ProcessResults);
free(cp);
}
@@ -713,11 +711,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
*pfile = 0;
}
if (file) {
- *pfile = (char*)malloc(strlen(file) + 1);
+ *pfile = strdup(file);
if (!*pfile) {
return 0;
}
- strcpy(*pfile, file);
}
/* If we are redirecting the pipe, do not share it or use a native
@@ -1469,6 +1466,11 @@ void kwsysProcess_Kill(kwsysProcess* cp)
for them to exit. */
}
+void kwsysProcess_KillPID(unsigned long process_id)
+{
+ kwsysProcessKillTree((DWORD)process_id);
+}
+
/*
Function executed for each pipe's thread. Argument is a pointer to
the kwsysProcessPipeData instance for this thread.
@@ -1607,9 +1609,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
}
ZeroMemory(cp->ProcessInformation,
sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands);
if (!cp->CommandExitCodes) {
return 0;
@@ -2362,9 +2362,7 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
{
/* Free the process information buffer. */
- if (self->Buffer) {
- free(self->Buffer);
- }
+ free(self->Buffer);
}
static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 26e84e0..fa3551c 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -45,9 +45,9 @@ RegularExpression::RegularExpression(const RegularExpression& rxp)
this->program = new char[this->progsize]; // Allocate storage
for (ind = this->progsize; ind-- != 0;) // Copy regular expresion
this->program[ind] = rxp.program[ind];
- this->startp[0] = rxp.startp[0]; // Copy pointers into last
- this->endp[0] = rxp.endp[0]; // Successful "find" operation
- this->regmust = rxp.regmust; // Copy field
+ // Copy pointers into last successful "find" operation
+ this->regmatch = rxp.regmatch;
+ this->regmust = rxp.regmust; // Copy field
if (rxp.regmust != 0) {
char* dum = rxp.program;
ind = 0;
@@ -78,9 +78,9 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp)
this->program = new char[this->progsize]; // Allocate storage
for (ind = this->progsize; ind-- != 0;) // Copy regular expresion
this->program[ind] = rxp.program[ind];
- this->startp[0] = rxp.startp[0]; // Copy pointers into last
- this->endp[0] = rxp.endp[0]; // Successful "find" operation
- this->regmust = rxp.regmust; // Copy field
+ // Copy pointers into last successful "find" operation
+ this->regmatch = rxp.regmatch;
+ this->regmust = rxp.regmust; // Copy field
if (rxp.regmust != 0) {
char* dum = rxp.program;
ind = 0;
@@ -123,8 +123,9 @@ bool RegularExpression::deep_equal(const RegularExpression& rxp) const
while (ind-- != 0) // Else while still characters
if (this->program[ind] != rxp.program[ind]) // If regexp are different
return false; // Return failure
- return (this->startp[0] == rxp.startp[0] && // Else if same start/end ptrs,
- this->endp[0] == rxp.endp[0]); // Return true
+ // Else if same start/end ptrs, return true
+ return (this->regmatch.start() == rxp.regmatch.start() &&
+ this->regmatch.end() == rxp.regmatch.end());
}
// The remaining code in this file is derived from the regular expression code
@@ -276,31 +277,35 @@ const unsigned char MAGIC = 0234;
/////////////////////////////////////////////////////////////////////////
/*
- * Global work variables for compile().
+ * Read only utility variables.
*/
-static const char* regparse; // Input-scan pointer.
-static int regnpar; // () count.
static char regdummy;
-static char* regcode; // Code-emit pointer; &regdummy = don't.
-static long regsize; // Code size.
+static char* const regdummyptr = &regdummy;
/*
- * Forward declarations for compile()'s friends.
+ * Utility class for RegularExpression::compile().
*/
-// #ifndef static
-// #define static static
-// #endif
-static char* reg(int, int*);
-static char* regbranch(int*);
-static char* regpiece(int*);
-static char* regatom(int*);
-static char* regnode(char);
+class RegExpCompile
+{
+public:
+ const char* regparse; // Input-scan pointer.
+ int regnpar; // () count.
+ char* regcode; // Code-emit pointer; regdummyptr = don't.
+ long regsize; // Code size.
+
+ char* reg(int, int*);
+ char* regbranch(int*);
+ char* regpiece(int*);
+ char* regatom(int*);
+ char* regnode(char);
+ void regc(char);
+ void reginsert(char, char*);
+ static void regtail(char*, const char*);
+ static void regoptail(char*, const char*);
+};
+
static const char* regnext(const char*);
static char* regnext(char*);
-static void regc(char);
-static void reginsert(char, char*);
-static void regtail(char*, const char*);
-static void regoptail(char*, const char*);
#ifdef STRCSPN
static int strcspn();
@@ -337,19 +342,20 @@ bool RegularExpression::compile(const char* exp)
}
// First pass: determine size, legality.
- regparse = exp;
- regnpar = 1;
- regsize = 0L;
- regcode = &regdummy;
- regc(static_cast<char>(MAGIC));
- if (!reg(0, &flags)) {
+ RegExpCompile comp;
+ comp.regparse = exp;
+ comp.regnpar = 1;
+ comp.regsize = 0L;
+ comp.regcode = regdummyptr;
+ comp.regc(static_cast<char>(MAGIC));
+ if (!comp.reg(0, &flags)) {
printf("RegularExpression::compile(): Error in compile.\n");
return false;
}
- this->startp[0] = this->endp[0] = this->searchstring = 0;
+ this->regmatch.clear();
// Small enough for pointer-storage convention?
- if (regsize >= 32767L) { // Probably could be 65535L.
+ if (comp.regsize >= 32767L) { // Probably could be 65535L.
// RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big),
printf("RegularExpression::compile(): Expression too big.\n");
return false;
@@ -360,8 +366,8 @@ bool RegularExpression::compile(const char* exp)
if (this->program != 0)
delete[] this->program;
//#endif
- this->program = new char[regsize];
- this->progsize = static_cast<int>(regsize);
+ this->program = new char[comp.regsize];
+ this->progsize = static_cast<int>(comp.regsize);
if (this->program == 0) {
// RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
@@ -370,11 +376,11 @@ bool RegularExpression::compile(const char* exp)
}
// Second pass: emit code.
- regparse = exp;
- regnpar = 1;
- regcode = this->program;
- regc(static_cast<char>(MAGIC));
- reg(0, &flags);
+ comp.regparse = exp;
+ comp.regnpar = 1;
+ comp.regcode = this->program;
+ comp.regc(static_cast<char>(MAGIC));
+ comp.reg(0, &flags);
// Dig out information for optimizations.
this->regstart = '\0'; // Worst-case defaults.
@@ -423,7 +429,7 @@ bool RegularExpression::compile(const char* exp)
* is a trifle forced, but the need to tie the tails of the branches to what
* follows makes it hard to avoid.
*/
-static char* reg(int paren, int* flagp)
+char* RegExpCompile::reg(int paren, int* flagp)
{
char* ret;
char* br;
@@ -435,7 +441,7 @@ static char* reg(int paren, int* flagp)
// Make an OPEN node, if parenthesized.
if (paren) {
- if (regnpar >= RegularExpression::NSUBEXP) {
+ if (regnpar >= RegularExpressionMatch::NSUBEXP) {
// RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
printf("RegularExpression::compile(): Too many parentheses.\n");
return 0;
@@ -501,7 +507,7 @@ static char* reg(int paren, int* flagp)
*
* Implements the concatenation operator.
*/
-static char* regbranch(int* flagp)
+char* RegExpCompile::regbranch(int* flagp)
{
char* ret;
char* chain;
@@ -538,7 +544,7 @@ static char* regbranch(int* flagp)
* It might seem that this node could be dispensed with entirely, but the
* endmarker role is not redundant.
*/
-static char* regpiece(int* flagp)
+char* RegExpCompile::regpiece(int* flagp)
{
char* ret;
char op;
@@ -605,7 +611,7 @@ static char* regpiece(int* flagp)
* faster to run. Backslashed characters are exceptions, each becoming a
* separate node; the code is simpler that way and it's not worth fixing.
*/
-static char* regatom(int* flagp)
+char* RegExpCompile::regatom(int* flagp)
{
char* ret;
int flags;
@@ -724,13 +730,13 @@ static char* regatom(int* flagp)
- regnode - emit a node
Location.
*/
-static char* regnode(char op)
+char* RegExpCompile::regnode(char op)
{
char* ret;
char* ptr;
ret = regcode;
- if (ret == &regdummy) {
+ if (ret == regdummyptr) {
regsize += 3;
return (ret);
}
@@ -747,9 +753,9 @@ static char* regnode(char op)
/*
- regc - emit (if appropriate) a byte of code
*/
-static void regc(char b)
+void RegExpCompile::regc(char b)
{
- if (regcode != &regdummy)
+ if (regcode != regdummyptr)
*regcode++ = b;
else
regsize++;
@@ -760,13 +766,13 @@ static void regc(char b)
*
* Means relocating the operand.
*/
-static void reginsert(char op, char* opnd)
+void RegExpCompile::reginsert(char op, char* opnd)
{
char* src;
char* dst;
char* place;
- if (regcode == &regdummy) {
+ if (regcode == regdummyptr) {
regsize += 3;
return;
}
@@ -786,13 +792,13 @@ static void reginsert(char op, char* opnd)
/*
- regtail - set the next-pointer at the end of a node chain
*/
-static void regtail(char* p, const char* val)
+void RegExpCompile::regtail(char* p, const char* val)
{
char* scan;
char* temp;
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return;
// Find last node.
@@ -815,10 +821,10 @@ static void regtail(char* p, const char* val)
/*
- regoptail - regtail on operand of first argument; nop if operandless
*/
-static void regoptail(char* p, const char* val)
+void RegExpCompile::regoptail(char* p, const char* val)
{
// "Operandless" and "op != BRANCH" are synonymous in practice.
- if (p == 0 || p == &regdummy || OP(p) != BRANCH)
+ if (p == 0 || p == regdummyptr || OP(p) != BRANCH)
return;
regtail(OPERAND(p), val);
}
@@ -830,34 +836,30 @@ static void regoptail(char* p, const char* val)
////////////////////////////////////////////////////////////////////////
/*
- * Global work variables for find().
+ * Utility class for RegularExpression::find().
*/
-static const char* reginput; // String-input pointer.
-static const char* regbol; // Beginning of input, for ^ check.
-static const char** regstartp; // Pointer to startp array.
-static const char** regendp; // Ditto for endp.
+class RegExpFind
+{
+public:
+ const char* reginput; // String-input pointer.
+ const char* regbol; // Beginning of input, for ^ check.
+ const char** regstartp; // Pointer to startp array.
+ const char** regendp; // Ditto for endp.
-/*
- * Forwards.
- */
-static int regtry(const char*, const char**, const char**, const char*);
-static int regmatch(const char*);
-static int regrepeat(const char*);
-
-#ifdef DEBUG
-int regnarrate = 0;
-void regdump();
-static char* regprop();
-#endif
+ int regtry(const char*, const char**, const char**, const char*);
+ int regmatch(const char*);
+ int regrepeat(const char*);
+};
// find -- Matches the regular expression to the given string.
// Returns true if found, and sets start and end indexes accordingly.
-
-bool RegularExpression::find(const char* string)
+bool RegularExpression::find(char const* string,
+ RegularExpressionMatch& rmatch) const
{
const char* s;
- this->searchstring = string;
+ rmatch.clear();
+ rmatch.searchstring = string;
if (!this->program) {
return false;
@@ -868,7 +870,7 @@ bool RegularExpression::find(const char* string)
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf(
"RegularExpression::find(): Compiled regular expression corrupted.\n");
- return 0;
+ return false;
}
// If there is a "must appear" string, look for it.
@@ -880,42 +882,45 @@ bool RegularExpression::find(const char* string)
s++;
}
if (s == 0) // Not present.
- return (0);
+ return false;
}
+ RegExpFind regFind;
+
// Mark beginning of line for ^ .
- regbol = string;
+ regFind.regbol = string;
// Simplest case: anchored match need be tried only once.
if (this->reganch)
- return (regtry(string, this->startp, this->endp, this->program) != 0);
+ return (
+ regFind.regtry(string, rmatch.startp, rmatch.endp, this->program) != 0);
// Messy cases: unanchored match.
s = string;
if (this->regstart != '\0')
// We know what char it must start with.
while ((s = strchr(s, this->regstart)) != 0) {
- if (regtry(s, this->startp, this->endp, this->program))
- return (1);
+ if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program))
+ return true;
s++;
}
else
// We don't -- general case.
do {
- if (regtry(s, this->startp, this->endp, this->program))
- return (1);
+ if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program))
+ return true;
} while (*s++ != '\0');
// Failure.
- return (0);
+ return false;
}
/*
- regtry - try match at specific point
0 failure, 1 success
*/
-static int regtry(const char* string, const char** start, const char** end,
- const char* prog)
+int RegExpFind::regtry(const char* string, const char** start,
+ const char** end, const char* prog)
{
int i;
const char** sp1;
@@ -927,7 +932,7 @@ static int regtry(const char* string, const char** start, const char** end,
sp1 = start;
ep = end;
- for (i = RegularExpression::NSUBEXP; i > 0; i--) {
+ for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) {
*sp1++ = 0;
*ep++ = 0;
}
@@ -950,7 +955,7 @@ static int regtry(const char* string, const char** start, const char** end,
* by recursion.
* 0 failure, 1 success
*/
-static int regmatch(const char* prog)
+int RegExpFind::regmatch(const char* prog)
{
const char* scan; // Current node.
const char* next; // Next node.
@@ -1129,7 +1134,7 @@ static int regmatch(const char* prog)
/*
- regrepeat - repeatedly match something simple, report how many
*/
-static int regrepeat(const char* p)
+int RegExpFind::regrepeat(const char* p)
{
int count = 0;
const char* scan;
@@ -1176,7 +1181,7 @@ static const char* regnext(const char* p)
{
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return (0);
offset = NEXT(p);
@@ -1193,7 +1198,7 @@ static char* regnext(char* p)
{
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return (0);
offset = NEXT(p);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index 606e3da..a3fe72d 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -34,6 +34,115 @@
namespace @KWSYS_NAMESPACE@ {
+// Forward declaration
+class RegularExpression;
+
+/** \class RegularExpressionMatch
+ * \brief Stores the pattern matches of a RegularExpression
+ */
+class @KWSYS_NAMESPACE@_EXPORT RegularExpressionMatch
+{
+public:
+ RegularExpressionMatch();
+
+ bool isValid() const;
+ void clear();
+
+ std::string::size_type start() const;
+ std::string::size_type end() const;
+ std::string::size_type start(int n) const;
+ std::string::size_type end(int n) const;
+ std::string match(int n) const;
+
+ enum
+ {
+ NSUBEXP = 10
+ };
+
+private:
+ friend class RegularExpression;
+ const char* startp[NSUBEXP];
+ const char* endp[NSUBEXP];
+ const char* searchstring;
+};
+
+/**
+ * \brief Creates an invalid match object
+ */
+inline RegularExpressionMatch::RegularExpressionMatch()
+{
+ startp[0] = 0;
+ endp[0] = 0;
+ searchstring = 0;
+}
+
+/**
+ * \brief Returns true if the match pointers are valid
+ */
+inline bool RegularExpressionMatch::isValid() const
+{
+ return (this->startp[0] != 0);
+}
+
+/**
+ * \brief Resets to the (invalid) construction state.
+ */
+inline void RegularExpressionMatch::clear()
+{
+ startp[0] = 0;
+ endp[0] = 0;
+ searchstring = 0;
+}
+
+/**
+ * \brief Returns the start index of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::start() const
+{
+ return static_cast<std::string::size_type>(this->startp[0] - searchstring);
+}
+
+/**
+ * \brief Returns the end index of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::end() const
+{
+ return static_cast<std::string::size_type>(this->endp[0] - searchstring);
+}
+
+/**
+ * \brief Returns the start index of nth submatch.
+ * start(0) is the start of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::start(int n) const
+{
+ return static_cast<std::string::size_type>(this->startp[n] -
+ this->searchstring);
+}
+
+/**
+ * \brief Returns the end index of nth submatch.
+ * end(0) is the end of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::end(int n) const
+{
+ return static_cast<std::string::size_type>(this->endp[n] -
+ this->searchstring);
+}
+
+/**
+ * \brief Returns the nth submatch as a string.
+ */
+inline std::string RegularExpressionMatch::match(int n) const
+{
+ if (this->startp[n] == 0) {
+ return std::string();
+ } else {
+ return std::string(this->startp[n], static_cast<std::string::size_type>(
+ this->endp[n] - this->startp[n]));
+ }
+}
+
/** \class RegularExpression
* \brief Implements pattern matching with regular expressions.
*
@@ -109,12 +218,12 @@ namespace @KWSYS_NAMESPACE@ {
* object as an argument and creates an object initialized with the
* information from the given RegularExpression object.
*
- * The find member function finds the first occurence of the regualr
+ * The find member function finds the first occurrence of the regular
* expression of that object in the string given to find as an argument. Find
* returns a boolean, and if true, mutates the private data appropriately.
* Find sets pointers to the beginning and end of the thing last found, they
* are pointers into the actual string that was searched. The start and end
- * member functions return indicies into the searched string that correspond
+ * member functions return indices into the searched string that correspond
* to the beginning and end pointers respectively. The compile member
* function takes a char* and puts the compiled version of the char* argument
* into the object's private data fields. The == and != operators only check
@@ -170,6 +279,9 @@ namespace @KWSYS_NAMESPACE@ {
* the same as the two characters before the first p encounterd in
* the line. It would match "drepa qrepb" in "rep drepa qrepb".
*
+ * All methods of RegularExpression can be called simultaneously from
+ * different threads but only if each invocation uses an own instance of
+ * RegularExpression.
*/
class @KWSYS_NAMESPACE@_EXPORT RegularExpression
{
@@ -213,9 +325,19 @@ public:
/**
* Matches the regular expression to the given string.
+ * Returns true if found, and sets start and end indexes
+ * in the RegularExpressionMatch instance accordingly.
+ *
+ * This method is thread safe when called with different
+ * RegularExpressionMatch instances.
+ */
+ bool find(char const*, RegularExpressionMatch&) const;
+
+ /**
+ * Matches the regular expression to the given string.
* Returns true if found, and sets start and end indexes accordingly.
*/
- bool find(char const*);
+ inline bool find(char const*);
/**
* Matches the regular expression to the given std string.
@@ -224,14 +346,18 @@ public:
inline bool find(std::string const&);
/**
- * Index to start of first find.
+ * Match indices
*/
+ inline RegularExpressionMatch const& regMatch() const;
inline std::string::size_type start() const;
+ inline std::string::size_type end() const;
+ inline std::string::size_type start(int n) const;
+ inline std::string::size_type end(int n) const;
/**
- * Index to end of first find.
+ * Match strings
*/
- inline std::string::size_type end() const;
+ inline std::string match(int n) const;
/**
* Copy the given regular expression.
@@ -266,29 +392,14 @@ public:
*/
inline void set_invalid();
- /**
- * Destructor.
- */
- // awf added
- std::string::size_type start(int n) const;
- std::string::size_type end(int n) const;
- std::string match(int n) const;
-
- enum
- {
- NSUBEXP = 10
- };
-
private:
- const char* startp[NSUBEXP];
- const char* endp[NSUBEXP];
+ RegularExpressionMatch regmatch;
char regstart; // Internal use only
char reganch; // Internal use only
const char* regmust; // Internal use only
std::string::size_type regmlen; // Internal use only
char* program;
int progsize;
- const char* searchstring;
};
/**
@@ -344,51 +455,42 @@ inline bool RegularExpression::compile(std::string const& s)
* Matches the regular expression to the given std string.
* Returns true if found, and sets start and end indexes accordingly.
*/
-inline bool RegularExpression::find(std::string const& s)
+inline bool RegularExpression::find(const char* s)
{
- return this->find(s.c_str());
+ return this->find(s, this->regmatch);
}
/**
- * Set the start position for the regular expression.
+ * Matches the regular expression to the given std string.
+ * Returns true if found, and sets start and end indexes accordingly.
*/
-inline std::string::size_type RegularExpression::start() const
+inline bool RegularExpression::find(std::string const& s)
{
- return static_cast<std::string::size_type>(this->startp[0] - searchstring);
+ return this->find(s.c_str());
}
/**
- * Returns the start/end index of the last item found.
+ * Returns the internal match object
*/
-inline std::string::size_type RegularExpression::end() const
+inline RegularExpressionMatch const& RegularExpression::regMatch() const
{
- return static_cast<std::string::size_type>(this->endp[0] - searchstring);
+ return this->regmatch;
}
/**
- * Returns true if two regular expressions have different
- * compiled program for pattern matching.
+ * Returns the start index of the full match.
*/
-inline bool RegularExpression::operator!=(const RegularExpression& r) const
+inline std::string::size_type RegularExpression::start() const
{
- return (!(*this == r));
+ return regmatch.start();
}
/**
- * Returns true if a valid regular expression is compiled
- * and ready for pattern matching.
+ * Returns the end index of the full match.
*/
-inline bool RegularExpression::is_valid() const
-{
- return (this->program != 0);
-}
-
-inline void RegularExpression::set_invalid()
+inline std::string::size_type RegularExpression::end() const
{
- //#ifndef _WIN32
- delete[] this->program;
- //#endif
- this->program = 0;
+ return regmatch.end();
}
/**
@@ -396,7 +498,7 @@ inline void RegularExpression::set_invalid()
*/
inline std::string::size_type RegularExpression::start(int n) const
{
- return static_cast<std::string::size_type>(this->startp[n] - searchstring);
+ return regmatch.start(n);
}
/**
@@ -404,7 +506,7 @@ inline std::string::size_type RegularExpression::start(int n) const
*/
inline std::string::size_type RegularExpression::end(int n) const
{
- return static_cast<std::string::size_type>(this->endp[n] - searchstring);
+ return regmatch.end(n);
}
/**
@@ -412,12 +514,33 @@ inline std::string::size_type RegularExpression::end(int n) const
*/
inline std::string RegularExpression::match(int n) const
{
- if (this->startp[n] == 0) {
- return std::string("");
- } else {
- return std::string(this->startp[n], static_cast<std::string::size_type>(
- this->endp[n] - this->startp[n]));
- }
+ return regmatch.match(n);
+}
+
+/**
+ * Returns true if two regular expressions have different
+ * compiled program for pattern matching.
+ */
+inline bool RegularExpression::operator!=(const RegularExpression& r) const
+{
+ return (!(*this == r));
+}
+
+/**
+ * Returns true if a valid regular expression is compiled
+ * and ready for pattern matching.
+ */
+inline bool RegularExpression::is_valid() const
+{
+ return (this->program != 0);
+}
+
+inline void RegularExpression::set_invalid()
+{
+ //#ifndef _WIN32
+ delete[] this->program;
+ //#endif
+ this->program = 0;
}
} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 86fdccd..ab1f40a 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -1346,7 +1346,7 @@ std::string SymbolProperties::GetBinary() const
std::string binary;
char buf[1024] = { '\0' };
ssize_t ll = 0;
- if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0) {
+ if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0 && ll < 1024) {
buf[ll] = '\0';
binary = buf;
} else {
@@ -3633,7 +3633,7 @@ SystemInformationImplementation::GetHostMemoryAvailable(
// apply resource limits across groups of processes.
// this is of use on certain SMP systems (eg. SGI UV)
// where the host has a large amount of ram but a given user's
- // access to it is severly restricted. The system will
+ // access to it is severely restricted. The system will
// apply a limit across a set of processes. Units are in KiB.
if (hostLimitEnvVarName) {
const char* hostLimitEnvVarValue = getenv(hostLimitEnvVarName);
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index 516c505..5678e8a 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -124,7 +124,7 @@ public:
// are the processes comprising an mpi program which is running in
// parallel. The amount of memory reported may differ from the host
// total if a host wide resource limit is applied. Such reource limits
- // are reported to us via an applicaiton specified environment variable.
+ // are reported to us via an application specified environment variable.
LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = NULL);
// Get total system RAM in units of KiB available to this process.
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ecfa331..f547362 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -20,12 +20,14 @@
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
#include KWSYS_HEADER(FStream.hxx)
+#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(Encoding.hxx)
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
+#include <utility>
#include <vector>
// Work-around CMake dependency scanning limitation. This must
@@ -227,13 +229,17 @@ inline const char* Getcwd(char* buf, unsigned int len)
{
std::vector<wchar_t> w_buf(len);
if (_wgetcwd(&w_buf[0], len)) {
- // make sure the drive letter is capital
- if (wcslen(&w_buf[0]) > 1 && w_buf[1] == L':') {
- w_buf[0] = towupper(w_buf[0]);
+ size_t nlen = kwsysEncoding_wcstombs(buf, &w_buf[0], len);
+ if (nlen == static_cast<size_t>(-1)) {
+ return 0;
+ }
+ if (nlen < len) {
+ // make sure the drive letter is capital
+ if (nlen > 1 && buf[1] == ':') {
+ buf[0] = toupper(buf[0]);
+ }
+ return buf;
}
- std::string tmp = KWSYS_NAMESPACE::Encoding::ToNarrow(&w_buf[0]);
- strcpy(buf, tmp.c_str());
- return buf;
}
return 0;
}
@@ -746,15 +752,15 @@ FILE* SystemTools::Fopen(const std::string& file, const char* mode)
#endif
}
-bool SystemTools::MakeDirectory(const char* path)
+bool SystemTools::MakeDirectory(const char* path, const mode_t* mode)
{
if (!path) {
return false;
}
- return SystemTools::MakeDirectory(std::string(path));
+ return SystemTools::MakeDirectory(std::string(path), mode);
}
-bool SystemTools::MakeDirectory(const std::string& path)
+bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
{
if (SystemTools::PathExists(path)) {
return SystemTools::FileIsDirectory(path);
@@ -769,8 +775,12 @@ bool SystemTools::MakeDirectory(const std::string& path)
std::string topdir;
while ((pos = dir.find('/', pos)) != std::string::npos) {
topdir = dir.substr(0, pos);
- Mkdir(topdir);
- pos++;
+
+ if (Mkdir(topdir) == 0 && mode != 0) {
+ SystemTools::SetPermissions(topdir, *mode);
+ }
+
+ ++pos;
}
topdir = dir;
if (Mkdir(topdir) != 0) {
@@ -785,7 +795,10 @@ bool SystemTools::MakeDirectory(const std::string& path)
) {
return false;
}
+ } else if (mode != 0) {
+ SystemTools::SetPermissions(topdir, *mode);
}
+
return true;
}
@@ -1679,7 +1692,7 @@ bool SystemTools::StringEndsWith(const std::string& str1, const char* str2)
: false;
}
-// Returns a pointer to the last occurence of str2 in str1
+// Returns a pointer to the last occurrence of str2 in str1
const char* SystemTools::FindLastString(const char* str1, const char* str2)
{
if (!str1 || !str2) {
@@ -2496,6 +2509,14 @@ bool SystemTools::RemoveFile(const std::string& source)
if (IsJunction(ws) && DeleteJunction(ws)) {
return true;
}
+ const DWORD DIRECTORY_SOFT_LINK_ATTRS =
+ FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
+ DWORD attrs = GetFileAttributesW(ws.c_str());
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ (attrs & DIRECTORY_SOFT_LINK_ATTRS) == DIRECTORY_SOFT_LINK_ATTRS &&
+ RemoveDirectoryW(ws.c_str())) {
+ return true;
+ }
if (DeleteFileW(ws.c_str()) || GetLastError() == ERROR_FILE_NOT_FOUND ||
GetLastError() == ERROR_PATH_NOT_FOUND) {
return true;
@@ -3360,7 +3381,7 @@ std::string SystemTools::RelativePath(const std::string& local,
}
#ifdef _WIN32
-static std::string GetCasePathName(std::string const& pathIn)
+static std::pair<std::string, bool> GetCasePathName(std::string const& pathIn)
{
std::string casePath;
std::vector<std::string> path_components;
@@ -3369,7 +3390,7 @@ static std::string GetCasePathName(std::string const& pathIn)
{
// Relative paths cannot be converted.
casePath = pathIn;
- return casePath;
+ return std::make_pair(casePath, false);
}
// Start with root component.
@@ -3421,7 +3442,7 @@ static std::string GetCasePathName(std::string const& pathIn)
casePath += path_components[idx];
}
- return casePath;
+ return std::make_pair(casePath, converting);
}
#endif
@@ -3436,12 +3457,14 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p)
if (i != SystemTools::PathCaseMap->end()) {
return i->second;
}
- std::string casePath = GetCasePathName(p);
- if (casePath.size() > MAX_PATH) {
- return casePath;
+ std::pair<std::string, bool> casePath = GetCasePathName(p);
+ if (casePath.first.size() > MAX_PATH) {
+ return casePath.first;
}
- (*SystemTools::PathCaseMap)[p] = casePath;
- return casePath;
+ if (casePath.second) {
+ (*SystemTools::PathCaseMap)[p] = casePath.first;
+ }
+ return casePath.first;
#endif
}
@@ -4219,11 +4242,16 @@ bool SystemTools::IsSubDirectory(const std::string& cSubdir,
std::string dir = cDir;
SystemTools::ConvertToUnixSlashes(subdir);
SystemTools::ConvertToUnixSlashes(dir);
- if (subdir.size() > dir.size() && subdir[dir.size()] == '/') {
- std::string s = subdir.substr(0, dir.size());
- return SystemTools::ComparePath(s, dir);
+ if (subdir.size() <= dir.size() || dir.empty()) {
+ return false;
}
- return false;
+ bool isRootPath = *dir.rbegin() == '/'; // like "/" or "C:/"
+ size_t expectedSlashPosition = isRootPath ? dir.size() - 1u : dir.size();
+ if (subdir[expectedSlashPosition] != '/') {
+ return false;
+ }
+ std::string s = subdir.substr(0, dir.size());
+ return SystemTools::ComparePath(s, dir);
}
void SystemTools::Delay(unsigned int msec)
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 35bc1b1..8a02b75 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -107,7 +107,7 @@ public:
}
/**
- * Replace replace all occurences of the string in the source string.
+ * Replace replace all occurrences of the string in the source string.
*/
static void ReplaceString(std::string& source, const char* replace,
const char* with);
@@ -175,7 +175,7 @@ public:
static bool StringEndsWith(const std::string& str1, const char* str2);
/**
- * Returns a pointer to the last occurence of str2 in str1
+ * Returns a pointer to the last occurrence of str2 in str1
*/
static const char* FindLastString(const char* str1, const char* str2);
@@ -553,13 +553,20 @@ public:
*/
static FILE* Fopen(const std::string& file, const char* mode);
+/**
+ * Visual C++ does not define mode_t (note that Borland does, however).
+ */
+#if defined(_MSC_VER)
+ typedef unsigned short mode_t;
+#endif
+
/**
* 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.
*/
- static bool MakeDirectory(const char* path);
- static bool MakeDirectory(const std::string& path);
+ static bool MakeDirectory(const char* path, const mode_t* mode = 0);
+ static bool MakeDirectory(const std::string& path, const mode_t* mode = 0);
/**
* Copy the source file to the destination file only
@@ -749,13 +756,6 @@ public:
*/
static long int CreationTime(const std::string& filename);
-/**
- * Visual C++ does not define mode_t (note that Borland does, however).
- */
-#if defined(_MSC_VER)
- typedef unsigned short mode_t;
-#endif
-
/**
* Get and set permissions of the file. If honor_umask is set, the umask
* is queried and applied to the given permissions. Returns false if
@@ -905,7 +905,7 @@ public:
/**
* Delay the execution for a specified amount of time specified
- * in miliseconds
+ * in milliseconds
*/
static void Delay(unsigned int msec);
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
index 3f9174f..8c9b81e 100644
--- a/Source/kwsys/hash_map.hxx.in
+++ b/Source/kwsys/hash_map.hxx.in
@@ -49,7 +49,7 @@ namespace @KWSYS_NAMESPACE@ {
// select1st is an extension: it is not part of the standard.
template <class T1, class T2>
-struct hash_select1st : public std::unary_function<std::pair<T1, T2>, T1>
+struct hash_select1st
{
const T1& operator()(const std::pair<T1, T2>& __x) const
{
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
index e3a0c6c..5edd367 100644
--- a/Source/kwsys/hash_set.hxx.in
+++ b/Source/kwsys/hash_set.hxx.in
@@ -49,7 +49,7 @@ namespace @KWSYS_NAMESPACE@ {
// identity is an extension: it is not part of the standard.
template <class _Tp>
-struct _Identity : public std::unary_function<_Tp, _Tp>
+struct _Identity
{
const _Tp& operator()(const _Tp& __x) const { return __x; }
};
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
index dd92cb9..e962f17 100644
--- a/Source/kwsys/hashtable.hxx.in
+++ b/Source/kwsys/hashtable.hxx.in
@@ -35,13 +35,12 @@
#include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <algorithm> // lower_bound
-#include <functional> // unary_function
-#include <iterator> // iterator_traits
-#include <memory> // allocator
-#include <stddef.h> // size_t
-#include <utility> // pair
-#include <vector> // vector
+#include <algorithm> // lower_bound
+#include <iterator> // iterator_traits
+#include <memory> // allocator
+#include <stddef.h> // size_t
+#include <utility> // pair
+#include <vector> // vector
#if defined(_MSC_VER)
#pragma warning(push)
diff --git a/Source/kwsys/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c
index 64a361b..5432633 100644
--- a/Source/kwsys/kwsysPlatformTestsC.c
+++ b/Source/kwsys/kwsysPlatformTestsC.c
@@ -55,6 +55,21 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
}
#endif
+#ifdef TEST_KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+#if defined(__APPLE__)
+#include <AvailabilityMacros.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+#error "clock_gettime not available on macOS < 10.12"
+#endif
+#endif
+#include <time.h>
+int KWSYS_PLATFORM_TEST_C_MAIN()
+{
+ struct timespec ts;
+ return clock_gettime(CLOCK_MONOTONIC, &ts);
+}
+#endif
+
#ifdef TEST_KWSYS_C_TYPE_MACROS
char* info_macros =
#if defined(__SIZEOF_SHORT__)
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index e67d436..f1f9ed3 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -281,7 +281,7 @@ int main()
#ifdef TEST_KWSYS_CXX_HAS_BACKTRACE
#if defined(__PATHSCALE__) || defined(__PATHCC__) || \
(defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41))
-backtrace doesnt work with this compiler or os
+backtrace does not work with this compiler or os
#endif
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE
diff --git a/Source/kwsys/testConfigure.cxx b/Source/kwsys/testConfigure.cxx
new file mode 100644
index 0000000..916dcc1
--- /dev/null
+++ b/Source/kwsys/testConfigure.cxx
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Configure.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+#include "Configure.hxx.in"
+#endif
+
+static bool testFallthrough(int n)
+{
+ int r = 0;
+ switch (n) {
+ case 1:
+ ++r;
+ KWSYS_FALLTHROUGH;
+ default:
+ ++r;
+ }
+ return r == 2;
+}
+
+int testConfigure(int, char* [])
+{
+ bool res = true;
+ res = testFallthrough(1) && res;
+ return res ? 0 : 1;
+}
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 2c5ef46..2742fe4 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -75,6 +75,10 @@ static int testRobustEncoding()
// test that the conversion functions handle invalid
// unicode correctly/gracefully
+ // we manipulate the format flags of stdout, remember
+ // the original state here to restore before return
+ std::ios::fmtflags const& flags = std::cout.flags();
+
int ret = 0;
char cstr[] = { (char)-1, 0 };
// this conversion could fail
@@ -120,6 +124,7 @@ static int testRobustEncoding()
ret++;
}
+ std::cout.flags(flags);
return ret;
}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 092dd03..4b4978d 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -107,6 +107,7 @@ static int test3(int argc, const char* argv[])
static int test4(int argc, const char* argv[])
{
+#ifndef CRASH_USING_ABORT
/* Prepare a pointer to an invalid address. Don't use null, because
dereferencing null is undefined behaviour and compilers are free to
do whatever they want. ex: Clang will warn at compile time, or even
@@ -114,6 +115,7 @@ static int test4(int argc, const char* argv[])
'volatile' and a slightly larger address, based on a runtime value. */
volatile int* invalidAddress = 0;
invalidAddress += argc ? 1 : 2;
+#endif
#if defined(_WIN32)
/* Avoid error diagnostic popups since we are crashing on purpose. */
@@ -128,9 +130,13 @@ static int test4(int argc, const char* argv[])
fprintf(stderr, "Output before crash on stderr from crash test.\n");
fflush(stdout);
fflush(stderr);
+#ifdef CRASH_USING_ABORT
+ abort();
+#else
assert(invalidAddress); /* Quiet Clang scan-build. */
/* Provoke deliberate crash by writing to the invalid address. */
*invalidAddress = 0;
+#endif
fprintf(stdout, "Output after crash on stdout from crash test.\n");
fprintf(stderr, "Output after crash on stderr from crash test.\n");
return 0;
@@ -149,7 +155,12 @@ static int test5(int argc, const char* argv[])
fprintf(stderr, "Output on stderr before recursive test.\n");
fflush(stdout);
fflush(stderr);
- r = runChild(cmd, kwsysProcess_State_Exception, kwsysProcess_Exception_Fault,
+ r = runChild(cmd, kwsysProcess_State_Exception,
+#ifdef CRASH_USING_ABORT
+ kwsysProcess_Exception_Other,
+#else
+ kwsysProcess_Exception_Fault,
+#endif
1, 1, 1, 0, 15, 0, 1, 0, 0, 0);
fprintf(stdout, "Output on stdout after recursive test.\n");
fprintf(stderr, "Output on stderr after recursive test.\n");
@@ -628,11 +639,16 @@ int main(int argc, const char* argv[])
kwsysProcess_State_Exception /* Process group test */
};
int exceptions[10] = {
- kwsysProcess_Exception_None, kwsysProcess_Exception_None,
- kwsysProcess_Exception_None, kwsysProcess_Exception_Fault,
- kwsysProcess_Exception_None, kwsysProcess_Exception_None,
- kwsysProcess_Exception_None, kwsysProcess_Exception_None,
- kwsysProcess_Exception_None, kwsysProcess_Exception_Interrupt
+ kwsysProcess_Exception_None, kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+#ifdef CRASH_USING_ABORT
+ kwsysProcess_Exception_Other,
+#else
+ kwsysProcess_Exception_Fault,
+#endif
+ kwsysProcess_Exception_None, kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None, kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None, kwsysProcess_Exception_Interrupt
};
int values[10] = { 0, 123, 1, 1, 0, 0, 0, 0, 1, 1 };
int shares[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
@@ -687,9 +703,7 @@ int main(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
#if defined(_WIN32)
- if (argv0) {
- free(argv0);
- }
+ free(argv0);
#endif
return r;
} else if (argc > 2 && strcmp(argv[1], "0") == 0) {
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 768eb4d..a6af9cc 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -254,22 +254,22 @@ static bool CheckFileOperations()
}
// should work, was created as new file before
if (!kwsys::SystemTools::FileExists(testNewFile)) {
- std::cerr << "Problem with FileExists for: " << testNewDir << std::endl;
+ std::cerr << "Problem with FileExists for: " << testNewFile << std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) {
- std::cerr << "Problem with FileExists as C string for: " << testNewDir
+ std::cerr << "Problem with FileExists as C string for: " << testNewFile
<< std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile, true)) {
- std::cerr << "Problem with FileExists as file for: " << testNewDir
+ std::cerr << "Problem with FileExists as file for: " << testNewFile
<< std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) {
std::cerr << "Problem with FileExists as C string and file for: "
- << testNewDir << std::endl;
+ << testNewFile << std::endl;
res = false;
}
@@ -285,7 +285,7 @@ static bool CheckFileOperations()
}
// should work, was created as new file before
if (!kwsys::SystemTools::PathExists(testNewFile)) {
- std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
+ std::cerr << "Problem with PathExists for: " << testNewFile << std::endl;
res = false;
}
@@ -813,6 +813,39 @@ static bool CheckFind()
return res;
}
+static bool CheckIsSubDirectory()
+{
+ bool res = true;
+
+ if (kwsys::SystemTools::IsSubDirectory("/foo", "/") == false) {
+ std::cerr << "Problem with IsSubDirectory (root - unix): " << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::IsSubDirectory("c:/foo", "c:/") == false) {
+ std::cerr << "Problem with IsSubDirectory (root - dos): " << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::IsSubDirectory("/foo/bar", "/foo") == false) {
+ std::cerr << "Problem with IsSubDirectory (deep): " << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::IsSubDirectory("/foo", "/foo") == true) {
+ std::cerr << "Problem with IsSubDirectory (identity): " << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::IsSubDirectory("/fooo", "/foo") == true) {
+ std::cerr << "Problem with IsSubDirectory (substring): " << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::IsSubDirectory("/foo/", "/foo") == true) {
+ std::cerr << "Problem with IsSubDirectory (prepended slash): "
+ << std::endl;
+ res = false;
+ }
+
+ return res;
+}
+
static bool CheckGetLineFromStream()
{
const std::string fileWithFiveCharsOnFirstLine(TEST_SYSTEMTOOLS_SOURCE_DIR
@@ -897,6 +930,8 @@ int testSystemTools(int, char* [])
res &= CheckFind();
+ res &= CheckIsSubDirectory();
+
res &= CheckGetLineFromStream();
res &= CheckGetFilenameName();