mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-10-07 04:02:23 +03:00
Merge branch 'upstream-KWSys' into update-kwsys
* upstream-KWSys: KWSys 2016-11-09 (18c65411)
This commit is contained in:
commit
95a97a40e4
72 files changed
+11588
-13715
No files matched your search
+87
-131
@@ -1,65 +1,43 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Base64.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Base64.h.in"
|
||||
#include "Base64.h.in"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static const unsigned char kwsysBase64EncodeTable[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static const unsigned char kwsysBase64DecodeTable[256] =
|
||||
{
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F,
|
||||
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
|
||||
0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
|
||||
0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
|
||||
0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
|
||||
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
|
||||
0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
|
||||
0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
|
||||
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
|
||||
0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
static const unsigned char kwsysBase64DecodeTable[256] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
|
||||
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
|
||||
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/*------------------------------------*/
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -76,27 +54,30 @@ static unsigned char kwsysBase64DecodeChar(unsigned char c)
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Encode 3 bytes into a 4 byte string. */
|
||||
void kwsysBase64_Encode3(const unsigned char *src, unsigned char *dest)
|
||||
void kwsysBase64_Encode3(const unsigned char* src, unsigned char* dest)
|
||||
{
|
||||
dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
|
||||
dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
|
||||
dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C)|((src[2] >> 6) & 0x03));
|
||||
dest[1] =
|
||||
kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F));
|
||||
dest[2] =
|
||||
kwsysBase64EncodeChar(((src[1] << 2) & 0x3C) | ((src[2] >> 6) & 0x03));
|
||||
dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Encode 2 bytes into a 4 byte string. */
|
||||
void kwsysBase64_Encode2(const unsigned char *src, unsigned char *dest)
|
||||
void kwsysBase64_Encode2(const unsigned char* src, unsigned char* dest)
|
||||
{
|
||||
dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
|
||||
dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
|
||||
dest[1] =
|
||||
kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F));
|
||||
dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C));
|
||||
dest[3] = '=';
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Encode 1 bytes into a 4 byte string. */
|
||||
void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest)
|
||||
void kwsysBase64_Encode1(const unsigned char* src, unsigned char* dest)
|
||||
{
|
||||
dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
|
||||
dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30));
|
||||
@@ -115,54 +96,48 @@ void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest)
|
||||
actually knowing how much data to expect (if the input is not a multiple of
|
||||
3 bytes then the extra padding needed to complete the encode 4 bytes will
|
||||
stop the decoding anyway). */
|
||||
size_t kwsysBase64_Encode(const unsigned char *input,
|
||||
size_t length,
|
||||
unsigned char *output,
|
||||
int mark_end)
|
||||
size_t kwsysBase64_Encode(const unsigned char* input, size_t length,
|
||||
unsigned char* output, int mark_end)
|
||||
{
|
||||
const unsigned char *ptr = input;
|
||||
const unsigned char *end = input + length;
|
||||
unsigned char *optr = output;
|
||||
const unsigned char* ptr = input;
|
||||
const unsigned char* end = input + length;
|
||||
unsigned char* optr = output;
|
||||
|
||||
/* Encode complete triplet */
|
||||
|
||||
while ((end - ptr) >= 3)
|
||||
{
|
||||
while ((end - ptr) >= 3) {
|
||||
kwsysBase64_Encode3(ptr, optr);
|
||||
ptr += 3;
|
||||
optr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Encodes a 2-byte ending into 3 bytes and 1 pad byte and writes. */
|
||||
|
||||
if (end - ptr == 2)
|
||||
{
|
||||
if (end - ptr == 2) {
|
||||
kwsysBase64_Encode2(ptr, optr);
|
||||
optr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Encodes a 1-byte ending into 2 bytes and 2 pad bytes */
|
||||
|
||||
else if (end - ptr == 1)
|
||||
{
|
||||
|
||||
else if (end - ptr == 1) {
|
||||
kwsysBase64_Encode1(ptr, optr);
|
||||
optr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we need to mark the end */
|
||||
|
||||
else if (mark_end)
|
||||
{
|
||||
else if (mark_end) {
|
||||
optr[0] = optr[1] = optr[2] = optr[3] = '=';
|
||||
optr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return (size_t)(optr - output);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Decode 4 bytes into a 3 byte string. */
|
||||
int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
|
||||
int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest)
|
||||
{
|
||||
unsigned char d0, d1, d2, d3;
|
||||
|
||||
@@ -170,35 +145,32 @@ int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
|
||||
d1 = kwsysBase64DecodeChar(src[1]);
|
||||
d2 = kwsysBase64DecodeChar(src[2]);
|
||||
d3 = kwsysBase64DecodeChar(src[3]);
|
||||
|
||||
|
||||
/* Make sure all characters were valid */
|
||||
|
||||
if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the 3 bytes */
|
||||
|
||||
dest[0] = (unsigned char)(((d0 << 2) & 0xFC) | ((d1 >> 4) & 0x03));
|
||||
dest[1] = (unsigned char)(((d1 << 4) & 0xF0) | ((d2 >> 2) & 0x0F));
|
||||
dest[2] = (unsigned char)(((d2 << 6) & 0xC0) | ((d3 >> 0) & 0x3F));
|
||||
|
||||
|
||||
/* Return the number of bytes actually decoded */
|
||||
|
||||
if (src[2] == '=')
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (src[3] == '=')
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (src[2] == '=') {
|
||||
return 1;
|
||||
}
|
||||
if (src[3] == '=') {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Decode bytes from the input buffer and store the decoded stream
|
||||
/* Decode bytes from the input buffer and store the decoded stream
|
||||
into the output buffer until 'length' bytes have been decoded. Return the
|
||||
real length of the decoded stream (which should be equal to 'length'). Note
|
||||
that the output buffer must be allocated by the caller. If
|
||||
@@ -207,73 +179,57 @@ int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
|
||||
'length' parameter is ignored. This enables the caller to decode a stream
|
||||
without actually knowing how much decoded data to expect (of course, the
|
||||
buffer must be large enough). */
|
||||
size_t kwsysBase64_Decode(const unsigned char *input,
|
||||
size_t length,
|
||||
unsigned char *output,
|
||||
size_t max_input_length)
|
||||
size_t kwsysBase64_Decode(const unsigned char* input, size_t length,
|
||||
unsigned char* output, size_t max_input_length)
|
||||
{
|
||||
const unsigned char *ptr = input;
|
||||
unsigned char *optr = output;
|
||||
const unsigned char* ptr = input;
|
||||
unsigned char* optr = output;
|
||||
|
||||
/* Decode complete triplet */
|
||||
|
||||
if (max_input_length)
|
||||
{
|
||||
const unsigned char *end = input + max_input_length;
|
||||
while (ptr < end)
|
||||
{
|
||||
if (max_input_length) {
|
||||
const unsigned char* end = input + max_input_length;
|
||||
while (ptr < end) {
|
||||
int len = kwsysBase64_Decode3(ptr, optr);
|
||||
optr += len;
|
||||
if(len < 3)
|
||||
{
|
||||
if (len < 3) {
|
||||
return (size_t)(optr - output);
|
||||
}
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *oend = output + length;
|
||||
while ((oend - optr) >= 3)
|
||||
{
|
||||
ptr += 4;
|
||||
}
|
||||
} else {
|
||||
unsigned char* oend = output + length;
|
||||
while ((oend - optr) >= 3) {
|
||||
int len = kwsysBase64_Decode3(ptr, optr);
|
||||
optr += len;
|
||||
if(len < 3)
|
||||
{
|
||||
if (len < 3) {
|
||||
return (size_t)(optr - output);
|
||||
}
|
||||
ptr += 4;
|
||||
}
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
/* Decode the last triplet */
|
||||
|
||||
if (oend - optr == 2)
|
||||
{
|
||||
|
||||
if (oend - optr == 2) {
|
||||
unsigned char temp[3];
|
||||
int len = kwsysBase64_Decode3(ptr, temp);
|
||||
if(len >= 2)
|
||||
{
|
||||
if (len >= 2) {
|
||||
optr[0] = temp[0];
|
||||
optr[1] = temp[1];
|
||||
optr += 2;
|
||||
}
|
||||
else if(len > 0)
|
||||
{
|
||||
} else if (len > 0) {
|
||||
optr[0] = temp[0];
|
||||
optr += 1;
|
||||
}
|
||||
}
|
||||
else if (oend - optr == 1)
|
||||
{
|
||||
} else if (oend - optr == 1) {
|
||||
unsigned char temp[3];
|
||||
int len = kwsysBase64_Decode3(ptr, temp);
|
||||
if(len > 0)
|
||||
{
|
||||
if (len > 0) {
|
||||
optr[0] = temp[0];
|
||||
optr += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (size_t)(optr - output);
|
||||
}
|
||||
+35
-47
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Base64_h
|
||||
#define @KWSYS_NAMESPACE@_Base64_h
|
||||
|
||||
@@ -21,41 +12,40 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysBase64 kwsys_ns(Base64)
|
||||
# define kwsysBase64_Decode kwsys_ns(Base64_Decode)
|
||||
# define kwsysBase64_Decode3 kwsys_ns(Base64_Decode3)
|
||||
# define kwsysBase64_Encode kwsys_ns(Base64_Encode)
|
||||
# define kwsysBase64_Encode1 kwsys_ns(Base64_Encode1)
|
||||
# define kwsysBase64_Encode2 kwsys_ns(Base64_Encode2)
|
||||
# define kwsysBase64_Encode3 kwsys_ns(Base64_Encode3)
|
||||
#define kwsysBase64 kwsys_ns(Base64)
|
||||
#define kwsysBase64_Decode kwsys_ns(Base64_Decode)
|
||||
#define kwsysBase64_Decode3 kwsys_ns(Base64_Decode3)
|
||||
#define kwsysBase64_Encode kwsys_ns(Base64_Encode)
|
||||
#define kwsysBase64_Encode1 kwsys_ns(Base64_Encode1)
|
||||
#define kwsysBase64_Encode2 kwsys_ns(Base64_Encode2)
|
||||
#define kwsysBase64_Encode3 kwsys_ns(Base64_Encode3)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Encode 3 bytes into a 4 byte string.
|
||||
*/
|
||||
kwsysEXPORT void kwsysBase64_Encode3(const unsigned char *src,
|
||||
unsigned char *dest);
|
||||
kwsysEXPORT void kwsysBase64_Encode3(const unsigned char* src,
|
||||
unsigned char* dest);
|
||||
|
||||
/**
|
||||
* Encode 2 bytes into a 4 byte string.
|
||||
*/
|
||||
kwsysEXPORT void kwsysBase64_Encode2(const unsigned char *src,
|
||||
unsigned char *dest);
|
||||
kwsysEXPORT void kwsysBase64_Encode2(const unsigned char* src,
|
||||
unsigned char* dest);
|
||||
|
||||
/**
|
||||
* Encode 1 bytes into a 4 byte string.
|
||||
*/
|
||||
kwsysEXPORT void kwsysBase64_Encode1(const unsigned char *src,
|
||||
unsigned char *dest);
|
||||
kwsysEXPORT void kwsysBase64_Encode1(const unsigned char* src,
|
||||
unsigned char* dest);
|
||||
|
||||
/**
|
||||
* Encode 'length' bytes from the input buffer and store the encoded
|
||||
@@ -70,17 +60,16 @@ kwsysEXPORT void kwsysBase64_Encode1(const unsigned char *src,
|
||||
* the extra padding needed to complete the encode 4 bytes will stop
|
||||
* the decoding anyway).
|
||||
*/
|
||||
kwsysEXPORT size_t kwsysBase64_Encode(const unsigned char *input,
|
||||
size_t length,
|
||||
unsigned char *output,
|
||||
kwsysEXPORT size_t kwsysBase64_Encode(const unsigned char* input,
|
||||
size_t length, unsigned char* output,
|
||||
int mark_end);
|
||||
|
||||
/**
|
||||
* Decode 4 bytes into a 3 byte string. Returns the number of bytes
|
||||
* actually decoded.
|
||||
*/
|
||||
kwsysEXPORT int kwsysBase64_Decode3(const unsigned char *src,
|
||||
unsigned char *dest);
|
||||
kwsysEXPORT int kwsysBase64_Decode3(const unsigned char* src,
|
||||
unsigned char* dest);
|
||||
|
||||
/**
|
||||
* Decode bytes from the input buffer and store the decoded stream
|
||||
@@ -94,9 +83,8 @@ kwsysEXPORT int kwsysBase64_Decode3(const unsigned char *src,
|
||||
* much decoded data to expect (of course, the buffer must be large
|
||||
* enough).
|
||||
*/
|
||||
kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char *input,
|
||||
size_t length,
|
||||
unsigned char *output,
|
||||
kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char* input,
|
||||
size_t length, unsigned char* output,
|
||||
size_t max_input_length);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -106,17 +94,17 @@ kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char *input,
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysBase64
|
||||
# undef kwsysBase64_Decode
|
||||
# undef kwsysBase64_Decode3
|
||||
# undef kwsysBase64_Encode
|
||||
# undef kwsysBase64_Encode1
|
||||
# undef kwsysBase64_Encode2
|
||||
# undef kwsysBase64_Encode3
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysBase64
|
||||
#undef kwsysBase64_Decode
|
||||
#undef kwsysBase64_Decode3
|
||||
#undef kwsysBase64_Encode
|
||||
#undef kwsysBase64_Encode1
|
||||
#undef kwsysBase64_Encode2
|
||||
#undef kwsysBase64_Encode3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,14 +1,5 @@
|
||||
#=============================================================================
|
||||
# KWSys - Kitware System Library
|
||||
# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
|
||||
|
||||
# The Kitware System Library is intended to be included in other
|
||||
# projects. It is completely configurable in that the library's
|
||||
|
||||
@@ -24,6 +24,19 @@ KWSys has no independent issue tracker. After encountering an issue
|
||||
Otherwise please report the issue to the tracker for the project that
|
||||
hosts the copy of KWSys in which the problem was found.
|
||||
|
||||
Code Style
|
||||
==========
|
||||
|
||||
We use `clang-format`_ to define our style for C++ code in the KWSys source
|
||||
tree. See the `.clang-format`_ configuration file for our style settings.
|
||||
Use ``clang-format`` version 3.8 or higher to format source files.
|
||||
See also the `clang-format.bash`_ script.
|
||||
|
||||
.. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html
|
||||
.. _`.clang-format`: .clang-format
|
||||
.. _`clang-format.bash`: clang-format.bash
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
#=============================================================================
|
||||
# KWSys - Kitware System Library
|
||||
# Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
|
||||
|
||||
set(CTEST_PROJECT_NAME "KWSys")
|
||||
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(CommandLineArguments.hxx)
|
||||
|
||||
@@ -18,38 +9,37 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "CommandLineArguments.hxx.in"
|
||||
# include "Configure.hxx.in"
|
||||
# include "String.hxx.in"
|
||||
#include "CommandLineArguments.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#include "String.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (disable: 4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 1375 /* base class destructor not virtual */
|
||||
#pragma set woff 1375 /* base class destructor not virtual */
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
# define CommandLineArguments_DEBUG(x) \
|
||||
#define CommandLineArguments_DEBUG(x) \
|
||||
std::cout << __LINE__ << " CLA: " << x << std::endl
|
||||
#else
|
||||
# define CommandLineArguments_DEBUG(x)
|
||||
#define CommandLineArguments_DEBUG(x)
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//============================================================================
|
||||
@@ -63,24 +53,27 @@ struct CommandLineArgumentsCallbackStructure
|
||||
int VariableType;
|
||||
const char* Help;
|
||||
};
|
||||
|
||||
class CommandLineArgumentsVectorOfStrings :
|
||||
public std::vector<kwsys::String> {};
|
||||
class CommandLineArgumentsSetOfStrings :
|
||||
public std::set<kwsys::String> {};
|
||||
class CommandLineArgumentsMapOfStrucs :
|
||||
public std::map<kwsys::String,
|
||||
CommandLineArgumentsCallbackStructure> {};
|
||||
|
||||
class CommandLineArgumentsVectorOfStrings : public std::vector<kwsys::String>
|
||||
{
|
||||
};
|
||||
class CommandLineArgumentsSetOfStrings : public std::set<kwsys::String>
|
||||
{
|
||||
};
|
||||
class CommandLineArgumentsMapOfStrucs
|
||||
: public std::map<kwsys::String, CommandLineArgumentsCallbackStructure>
|
||||
{
|
||||
};
|
||||
|
||||
class CommandLineArgumentsInternal
|
||||
{
|
||||
public:
|
||||
CommandLineArgumentsInternal()
|
||||
{
|
||||
{
|
||||
this->UnknownArgumentCallback = 0;
|
||||
this->ClientData = 0;
|
||||
this->LastArgument = 0;
|
||||
}
|
||||
}
|
||||
|
||||
typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
|
||||
typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
|
||||
@@ -92,7 +85,7 @@ public:
|
||||
CallbacksMap Callbacks;
|
||||
|
||||
CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
|
||||
void* ClientData;
|
||||
void* ClientData;
|
||||
|
||||
VectorOfStrings::size_type LastArgument;
|
||||
|
||||
@@ -123,10 +116,9 @@ void CommandLineArguments::Initialize(int argc, const char* const argv[])
|
||||
|
||||
this->Initialize();
|
||||
this->Internals->Argv0 = argv[0];
|
||||
for ( cc = 1; cc < argc; cc ++ )
|
||||
{
|
||||
for (cc = 1; cc < argc; cc++) {
|
||||
this->ProcessArgument(argv[cc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -150,32 +142,25 @@ void CommandLineArguments::ProcessArgument(const char* arg)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CommandLineArguments::GetMatchedArguments(
|
||||
std::vector<std::string>* matches,
|
||||
const std::string& arg)
|
||||
std::vector<std::string>* matches, const std::string& arg)
|
||||
{
|
||||
matches->clear();
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
||||
|
||||
// Does the argument match to any we know about?
|
||||
for ( it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end();
|
||||
it ++ )
|
||||
{
|
||||
for (it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end(); it++) {
|
||||
const CommandLineArguments::Internal::String& parg = it->first;
|
||||
CommandLineArgumentsCallbackStructure *cs = &it->second;
|
||||
CommandLineArgumentsCallbackStructure* cs = &it->second;
|
||||
if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
|
||||
cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
|
||||
{
|
||||
if ( arg == parg )
|
||||
{
|
||||
cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT) {
|
||||
if (arg == parg) {
|
||||
matches->push_back(parg);
|
||||
}
|
||||
}
|
||||
else if ( arg.find( parg ) == 0 )
|
||||
{
|
||||
} else if (arg.find(parg) == 0) {
|
||||
matches->push_back(parg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return !matches->empty();
|
||||
}
|
||||
|
||||
@@ -184,163 +169,143 @@ int CommandLineArguments::Parse()
|
||||
{
|
||||
std::vector<std::string>::size_type cc;
|
||||
std::vector<std::string> matches;
|
||||
if ( this->StoreUnusedArgumentsFlag )
|
||||
{
|
||||
if (this->StoreUnusedArgumentsFlag) {
|
||||
this->Internals->UnusedArguments.clear();
|
||||
}
|
||||
for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
|
||||
{
|
||||
}
|
||||
for (cc = 0; cc < this->Internals->Argv.size(); cc++) {
|
||||
const std::string& arg = this->Internals->Argv[cc];
|
||||
CommandLineArguments_DEBUG("Process argument: " << arg);
|
||||
this->Internals->LastArgument = cc;
|
||||
if ( this->GetMatchedArguments(&matches, arg) )
|
||||
{
|
||||
if (this->GetMatchedArguments(&matches, arg)) {
|
||||
// Ok, we found one or more arguments that match what user specified.
|
||||
// Let's find the longest one.
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type kk;
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
|
||||
CommandLineArguments::Internal::String::size_type maxlen = 0;
|
||||
for ( kk = 0; kk < matches.size(); kk ++ )
|
||||
{
|
||||
if ( matches[kk].size() > maxlen )
|
||||
{
|
||||
for (kk = 0; kk < matches.size(); kk++) {
|
||||
if (matches[kk].size() > maxlen) {
|
||||
maxlen = matches[kk].size();
|
||||
maxidx = kk;
|
||||
}
|
||||
}
|
||||
}
|
||||
// So, the longest one is probably the right one. Now see if it has any
|
||||
// additional value
|
||||
CommandLineArgumentsCallbackStructure *cs
|
||||
= &this->Internals->Callbacks[matches[maxidx]];
|
||||
CommandLineArgumentsCallbackStructure* cs =
|
||||
&this->Internals->Callbacks[matches[maxidx]];
|
||||
const std::string& sarg = matches[maxidx];
|
||||
if ( cs->Argument != sarg )
|
||||
{
|
||||
if (cs->Argument != sarg) {
|
||||
abort();
|
||||
}
|
||||
switch ( cs->ArgumentType )
|
||||
{
|
||||
case NO_ARGUMENT:
|
||||
// No value
|
||||
if ( !this->PopulateVariable(cs, 0) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SPACE_ARGUMENT:
|
||||
if ( cc == this->Internals->Argv.size()-1 )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
CommandLineArguments_DEBUG("This is a space argument: " << arg
|
||||
<< " value: " << this->Internals->Argv[cc+1]);
|
||||
// Value is the next argument
|
||||
if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cc ++;
|
||||
break;
|
||||
case EQUAL_ARGUMENT:
|
||||
if ( arg.size() == sarg.size() || arg.at(sarg.size()) != '=' )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
// Value is everythng followed the '=' sign
|
||||
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case CONCAT_ARGUMENT:
|
||||
// Value is whatever follows the argument
|
||||
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MULTI_ARGUMENT:
|
||||
// Suck in all the rest of the arguments
|
||||
CommandLineArguments_DEBUG("This is a multi argument: " << arg);
|
||||
for (cc++; cc < this->Internals->Argv.size(); ++ cc )
|
||||
{
|
||||
const std::string& marg = this->Internals->Argv[cc];
|
||||
CommandLineArguments_DEBUG(" check multi argument value: " << marg);
|
||||
if ( this->GetMatchedArguments(&matches, marg) )
|
||||
{
|
||||
CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg);
|
||||
break;
|
||||
}
|
||||
CommandLineArguments_DEBUG(" populate multi argument value: " << marg);
|
||||
if ( !this->PopulateVariable(cs, marg.c_str()) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( cc != this->Internals->Argv.size() )
|
||||
{
|
||||
CommandLineArguments_DEBUG("Again End of multi argument " << arg);
|
||||
cc--;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << std::endl;
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle unknown arguments
|
||||
if ( this->Internals->UnknownArgumentCallback )
|
||||
{
|
||||
if ( !this->Internals->UnknownArgumentCallback(arg.c_str(),
|
||||
this->Internals->ClientData) )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
switch (cs->ArgumentType) {
|
||||
case NO_ARGUMENT:
|
||||
// No value
|
||||
if (!this->PopulateVariable(cs, 0)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case SPACE_ARGUMENT:
|
||||
if (cc == this->Internals->Argv.size() - 1) {
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
CommandLineArguments_DEBUG("This is a space argument: "
|
||||
<< arg << " value: "
|
||||
<< this->Internals->Argv[cc + 1]);
|
||||
// Value is the next argument
|
||||
if (!this->PopulateVariable(cs,
|
||||
this->Internals->Argv[cc + 1].c_str())) {
|
||||
return 0;
|
||||
}
|
||||
cc++;
|
||||
break;
|
||||
case EQUAL_ARGUMENT:
|
||||
if (arg.size() == sarg.size() || arg.at(sarg.size()) != '=') {
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
// Value is everythng followed the '=' sign
|
||||
if (!this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case CONCAT_ARGUMENT:
|
||||
// Value is whatever follows the argument
|
||||
if (!this->PopulateVariable(cs, arg.c_str() + sarg.size())) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MULTI_ARGUMENT:
|
||||
// Suck in all the rest of the arguments
|
||||
CommandLineArguments_DEBUG("This is a multi argument: " << arg);
|
||||
for (cc++; cc < this->Internals->Argv.size(); ++cc) {
|
||||
const std::string& marg = this->Internals->Argv[cc];
|
||||
CommandLineArguments_DEBUG(
|
||||
" check multi argument value: " << marg);
|
||||
if (this->GetMatchedArguments(&matches, marg)) {
|
||||
CommandLineArguments_DEBUG("End of multi argument "
|
||||
<< arg << " with value: " << marg);
|
||||
break;
|
||||
}
|
||||
CommandLineArguments_DEBUG(
|
||||
" populate multi argument value: " << marg);
|
||||
if (!this->PopulateVariable(cs, marg.c_str())) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (cc != this->Internals->Argv.size()) {
|
||||
CommandLineArguments_DEBUG("Again End of multi argument " << arg);
|
||||
cc--;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Got unknown argument type: \"" << cs->ArgumentType
|
||||
<< "\"" << std::endl;
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Handle unknown arguments
|
||||
if (this->Internals->UnknownArgumentCallback) {
|
||||
if (!this->Internals->UnknownArgumentCallback(
|
||||
arg.c_str(), this->Internals->ClientData)) {
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
else if ( this->StoreUnusedArgumentsFlag )
|
||||
{
|
||||
return 1;
|
||||
} else if (this->StoreUnusedArgumentsFlag) {
|
||||
CommandLineArguments_DEBUG("Store unused argument " << arg);
|
||||
this->Internals->UnusedArguments.push_back(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl;
|
||||
this->Internals->LastArgument --;
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
|
||||
{
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type size
|
||||
= this->Internals->Argv.size() - this->Internals->LastArgument + 1;
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type size =
|
||||
this->Internals->Argv.size() - this->Internals->LastArgument + 1;
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type cc;
|
||||
|
||||
// Copy Argv0 as the first argument
|
||||
char** args = new char*[ size ];
|
||||
args[0] = new char[ this->Internals->Argv0.size() + 1 ];
|
||||
char** args = new char*[size];
|
||||
args[0] = new char[this->Internals->Argv0.size() + 1];
|
||||
strcpy(args[0], this->Internals->Argv0.c_str());
|
||||
int cnt = 1;
|
||||
|
||||
// Copy everything after the LastArgument, since that was not parsed.
|
||||
for ( cc = this->Internals->LastArgument+1;
|
||||
cc < this->Internals->Argv.size(); cc ++ )
|
||||
{
|
||||
args[cnt] = new char[ this->Internals->Argv[cc].size() + 1];
|
||||
for (cc = this->Internals->LastArgument + 1;
|
||||
cc < this->Internals->Argv.size(); cc++) {
|
||||
args[cnt] = new char[this->Internals->Argv[cc].size() + 1];
|
||||
strcpy(args[cnt], this->Internals->Argv[cc].c_str());
|
||||
cnt ++;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
*argc = cnt;
|
||||
*argv = args;
|
||||
}
|
||||
@@ -348,25 +313,23 @@ void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv)
|
||||
{
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type size
|
||||
= this->Internals->UnusedArguments.size() + 1;
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type size =
|
||||
this->Internals->UnusedArguments.size() + 1;
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type cc;
|
||||
|
||||
// Copy Argv0 as the first argument
|
||||
char** args = new char*[ size ];
|
||||
args[0] = new char[ this->Internals->Argv0.size() + 1 ];
|
||||
char** args = new char*[size];
|
||||
args[0] = new char[this->Internals->Argv0.size() + 1];
|
||||
strcpy(args[0], this->Internals->Argv0.c_str());
|
||||
int cnt = 1;
|
||||
|
||||
// Copy everything after the LastArgument, since that was not parsed.
|
||||
for ( cc = 0;
|
||||
cc < this->Internals->UnusedArguments.size(); cc ++ )
|
||||
{
|
||||
kwsys::String &str = this->Internals->UnusedArguments[cc];
|
||||
args[cnt] = new char[ str.size() + 1];
|
||||
for (cc = 0; cc < this->Internals->UnusedArguments.size(); cc++) {
|
||||
kwsys::String& str = this->Internals->UnusedArguments[cc];
|
||||
args[cnt] = new char[str.size() + 1];
|
||||
strcpy(args[cnt], str.c_str());
|
||||
cnt ++;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
*argc = cnt;
|
||||
*argv = args;
|
||||
}
|
||||
@@ -375,84 +338,95 @@ void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv)
|
||||
void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv)
|
||||
{
|
||||
int cc;
|
||||
for ( cc = 0; cc < argc; ++ cc )
|
||||
{
|
||||
delete [] (*argv)[cc];
|
||||
}
|
||||
delete [] *argv;
|
||||
for (cc = 0; cc < argc; ++cc) {
|
||||
delete[](*argv)[cc];
|
||||
}
|
||||
delete[] * argv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type,
|
||||
CallbackType callback, void* call_data, const char* help)
|
||||
void CommandLineArguments::AddCallback(const char* argument,
|
||||
ArgumentTypeEnum type,
|
||||
CallbackType callback, void* call_data,
|
||||
const char* help)
|
||||
{
|
||||
CommandLineArgumentsCallbackStructure s;
|
||||
s.Argument = argument;
|
||||
s.Argument = argument;
|
||||
s.ArgumentType = type;
|
||||
s.Callback = callback;
|
||||
s.CallData = call_data;
|
||||
s.Callback = callback;
|
||||
s.CallData = call_data;
|
||||
s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
|
||||
s.Variable = 0;
|
||||
s.Help = help;
|
||||
s.Variable = 0;
|
||||
s.Help = help;
|
||||
|
||||
this->Internals->Callbacks[argument] = s;
|
||||
this->GenerateHelp();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
VariableTypeEnum vtype, void* variable, const char* help)
|
||||
void CommandLineArguments::AddArgument(const char* argument,
|
||||
ArgumentTypeEnum type,
|
||||
VariableTypeEnum vtype, void* variable,
|
||||
const char* help)
|
||||
{
|
||||
CommandLineArgumentsCallbackStructure s;
|
||||
s.Argument = argument;
|
||||
s.Argument = argument;
|
||||
s.ArgumentType = type;
|
||||
s.Callback = 0;
|
||||
s.CallData = 0;
|
||||
s.Callback = 0;
|
||||
s.CallData = 0;
|
||||
s.VariableType = vtype;
|
||||
s.Variable = variable;
|
||||
s.Help = help;
|
||||
s.Variable = variable;
|
||||
s.Help = help;
|
||||
|
||||
this->Internals->Callbacks[argument] = s;
|
||||
this->GenerateHelp();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define CommandLineArgumentsAddArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, \
|
||||
ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, variable, help); \
|
||||
#define CommandLineArgumentsAddArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddArgument(const char* argument, \
|
||||
ArgumentTypeEnum type, \
|
||||
ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, \
|
||||
variable, help); \
|
||||
}
|
||||
|
||||
CommandLineArgumentsAddArgumentMacro(BOOL, bool)
|
||||
CommandLineArgumentsAddArgumentMacro(INT, int)
|
||||
CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
|
||||
CommandLineArgumentsAddArgumentMacro(STRING, char*)
|
||||
CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string)
|
||||
CommandLineArgumentsAddArgumentMacro(BOOL, bool)
|
||||
CommandLineArgumentsAddArgumentMacro(INT, int)
|
||||
CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
|
||||
CommandLineArgumentsAddArgumentMacro(STRING, char*)
|
||||
CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string)
|
||||
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, std::vector<double>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, std::vector<char*>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, std::vector<std::string>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE,
|
||||
std::vector<double>)
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_STRING,
|
||||
std::vector<char*>)
|
||||
CommandLineArgumentsAddArgumentMacro(
|
||||
VECTOR_STL_STRING, std::vector<std::string>)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddBooleanArgument(const char* argument, \
|
||||
ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
|
||||
CommandLineArguments::type##_TYPE, variable, help); \
|
||||
#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddBooleanArgument( \
|
||||
const char* argument, ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
|
||||
CommandLineArguments::type##_TYPE, variable, help); \
|
||||
}
|
||||
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE,
|
||||
double)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(STRING,
|
||||
char*)
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(
|
||||
STL_STRING, std::string)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::SetClientData(void* client_data)
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::SetClientData(void* client_data)
|
||||
{
|
||||
this->Internals->ClientData = client_data;
|
||||
}
|
||||
@@ -467,36 +441,32 @@ void CommandLineArguments::SetUnknownArgumentCallback(
|
||||
//----------------------------------------------------------------------------
|
||||
const char* CommandLineArguments::GetHelp(const char* arg)
|
||||
{
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it
|
||||
= this->Internals->Callbacks.find(arg);
|
||||
if ( it == this->Internals->Callbacks.end() )
|
||||
{
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it =
|
||||
this->Internals->Callbacks.find(arg);
|
||||
if (it == this->Internals->Callbacks.end()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Since several arguments may point to the same argument, find the one this
|
||||
// one point to if this one is pointing to another argument.
|
||||
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
||||
for(;;)
|
||||
{
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator hit
|
||||
= this->Internals->Callbacks.find(cs->Help);
|
||||
if ( hit == this->Internals->Callbacks.end() )
|
||||
{
|
||||
CommandLineArgumentsCallbackStructure* cs = &(it->second);
|
||||
for (;;) {
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator hit =
|
||||
this->Internals->Callbacks.find(cs->Help);
|
||||
if (hit == this->Internals->Callbacks.end()) {
|
||||
break;
|
||||
}
|
||||
cs = &(hit->second);
|
||||
}
|
||||
cs = &(hit->second);
|
||||
}
|
||||
return cs->Help;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::SetLineLength(unsigned int ll)
|
||||
{
|
||||
if ( ll < 9 || ll > 1000 )
|
||||
{
|
||||
if (ll < 9 || ll > 1000) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->LineLength = ll;
|
||||
this->GenerateHelp();
|
||||
}
|
||||
@@ -517,76 +487,68 @@ unsigned int CommandLineArguments::GetLastArgument()
|
||||
void CommandLineArguments::GenerateHelp()
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
|
||||
// Collapse all arguments into the map of vectors of all arguments that do
|
||||
// the same thing.
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
||||
typedef std::map<CommandLineArguments::Internal::String,
|
||||
CommandLineArguments::Internal::SetOfStrings > MapArgs;
|
||||
CommandLineArguments::Internal::SetOfStrings>
|
||||
MapArgs;
|
||||
MapArgs mp;
|
||||
MapArgs::iterator mpit, smpit;
|
||||
for ( it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end();
|
||||
it ++ )
|
||||
{
|
||||
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
||||
for (it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end(); it++) {
|
||||
CommandLineArgumentsCallbackStructure* cs = &(it->second);
|
||||
mpit = mp.find(cs->Help);
|
||||
if ( mpit != mp.end() )
|
||||
{
|
||||
if (mpit != mp.end()) {
|
||||
mpit->second.insert(it->first);
|
||||
mp[it->first].insert(it->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mp[it->first].insert(it->first);
|
||||
}
|
||||
}
|
||||
for ( it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end();
|
||||
it ++ )
|
||||
{
|
||||
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
||||
}
|
||||
for (it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end(); it++) {
|
||||
CommandLineArgumentsCallbackStructure* cs = &(it->second);
|
||||
mpit = mp.find(cs->Help);
|
||||
if ( mpit != mp.end() )
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mp[it->first].insert(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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: clen += 0; break;
|
||||
case CommandLineArguments::CONCAT_ARGUMENT: clen += 3; break;
|
||||
case CommandLineArguments::SPACE_ARGUMENT: clen += 4; break;
|
||||
case CommandLineArguments::EQUAL_ARGUMENT: clen += 4; break;
|
||||
}
|
||||
if ( clen > maxlen )
|
||||
{
|
||||
switch (this->Internals->Callbacks[*sit].ArgumentType) {
|
||||
case CommandLineArguments::NO_ARGUMENT:
|
||||
clen += 0;
|
||||
break;
|
||||
case CommandLineArguments::CONCAT_ARGUMENT:
|
||||
clen += 3;
|
||||
break;
|
||||
case CommandLineArguments::SPACE_ARGUMENT:
|
||||
clen += 4;
|
||||
break;
|
||||
case CommandLineArguments::EQUAL_ARGUMENT:
|
||||
clen += 4;
|
||||
break;
|
||||
}
|
||||
if (clen > maxlen) {
|
||||
maxlen = clen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create format for that string
|
||||
char format[80];
|
||||
@@ -595,74 +557,69 @@ 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;
|
||||
char argument[100];
|
||||
sprintf(argument, "%s", sit->c_str());
|
||||
switch ( this->Internals->Callbacks[*sit].ArgumentType )
|
||||
{
|
||||
case CommandLineArguments::NO_ARGUMENT: break;
|
||||
case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break;
|
||||
case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break;
|
||||
case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break;
|
||||
case CommandLineArguments::MULTI_ARGUMENT: strcat(argument, " opt opt ..."); break;
|
||||
}
|
||||
switch (this->Internals->Callbacks[*sit].ArgumentType) {
|
||||
case CommandLineArguments::NO_ARGUMENT:
|
||||
break;
|
||||
case CommandLineArguments::CONCAT_ARGUMENT:
|
||||
strcat(argument, "opt");
|
||||
break;
|
||||
case CommandLineArguments::SPACE_ARGUMENT:
|
||||
strcat(argument, " opt");
|
||||
break;
|
||||
case CommandLineArguments::EQUAL_ARGUMENT:
|
||||
strcat(argument, "=opt");
|
||||
break;
|
||||
case CommandLineArguments::MULTI_ARGUMENT:
|
||||
strcat(argument, " opt opt ...");
|
||||
break;
|
||||
}
|
||||
char buffer[80];
|
||||
sprintf(buffer, format, argument);
|
||||
str << buffer;
|
||||
}
|
||||
}
|
||||
const char* ptr = this->Internals->Callbacks[mpit->first].Help;
|
||||
size_t len = strlen(ptr);
|
||||
int cnt = 0;
|
||||
while ( len > 0)
|
||||
{
|
||||
while (len > 0) {
|
||||
// If argument with help is longer than line length, split it on previous
|
||||
// space (or tab) and continue on the next line
|
||||
CommandLineArguments::Internal::String::size_type cc;
|
||||
for ( cc = 0; ptr[cc]; cc ++ )
|
||||
{
|
||||
if ( *ptr == ' ' || *ptr == '\t' )
|
||||
{
|
||||
ptr ++;
|
||||
len --;
|
||||
}
|
||||
for (cc = 0; ptr[cc]; cc++) {
|
||||
if (*ptr == ' ' || *ptr == '\t') {
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
if ( cnt > 0 )
|
||||
{
|
||||
for ( cc = 0; cc < maxlen; cc ++ )
|
||||
{
|
||||
}
|
||||
if (cnt > 0) {
|
||||
for (cc = 0; cc < maxlen; cc++) {
|
||||
str << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
CommandLineArguments::Internal::String::size_type skip = len;
|
||||
if ( skip > this->LineLength - maxlen )
|
||||
{
|
||||
if (skip > this->LineLength - maxlen) {
|
||||
skip = this->LineLength - maxlen;
|
||||
for ( cc = skip-1; cc > 0; cc -- )
|
||||
{
|
||||
if ( ptr[cc] == ' ' || ptr[cc] == '\t' )
|
||||
{
|
||||
for (cc = skip - 1; cc > 0; cc--) {
|
||||
if (ptr[cc] == ' ' || ptr[cc] == '\t') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( cc != 0 )
|
||||
{
|
||||
skip = cc;
|
||||
}
|
||||
}
|
||||
if (cc != 0) {
|
||||
skip = cc;
|
||||
}
|
||||
}
|
||||
str.write(ptr, static_cast<std::streamsize>(skip));
|
||||
str << std::endl;
|
||||
ptr += skip;
|
||||
len -= skip;
|
||||
cnt ++;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// This can help debugging help string
|
||||
str << endl;
|
||||
@@ -677,181 +634,176 @@ void CommandLineArguments::GenerateHelp()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
bool* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(bool* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES" )
|
||||
{
|
||||
if (value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES") {
|
||||
*variable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*variable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
int* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(int* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
*variable = static_cast<int>(strtol(value.c_str(), &res, 10));
|
||||
//if ( res && *res )
|
||||
// if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
double* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(double* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
*variable = strtod(value.c_str(), &res);
|
||||
//if ( res && *res )
|
||||
// if ( res && *res )
|
||||
// {
|
||||
// Can handle non-double
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
char** variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(char** variable,
|
||||
const std::string& value)
|
||||
{
|
||||
if ( *variable )
|
||||
{
|
||||
delete [] *variable;
|
||||
if (*variable) {
|
||||
delete[] * variable;
|
||||
*variable = 0;
|
||||
}
|
||||
*variable = new char[ value.size() + 1 ];
|
||||
}
|
||||
*variable = new char[value.size() + 1];
|
||||
strcpy(*variable, value.c_str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::string* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::string* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
*variable = value;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::vector<bool>* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::vector<bool>* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
bool val = false;
|
||||
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES" )
|
||||
{
|
||||
if (value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES") {
|
||||
val = true;
|
||||
}
|
||||
}
|
||||
variable->push_back(val);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::vector<int>* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::vector<int>* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
|
||||
//if ( res && *res )
|
||||
// if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::vector<double>* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::vector<double>* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
variable->push_back(strtod(value.c_str(), &res));
|
||||
//if ( res && *res )
|
||||
// if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::vector<char*>* variable, const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::vector<char*>* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
char* var = new char[ value.size() + 1 ];
|
||||
char* var = new char[value.size() + 1];
|
||||
strcpy(var, value.c_str());
|
||||
variable->push_back(var);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
std::vector<std::string>* variable,
|
||||
const std::string& value)
|
||||
void CommandLineArguments::PopulateVariable(std::vector<std::string>* variable,
|
||||
const std::string& value)
|
||||
{
|
||||
variable->push_back(value);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
|
||||
const char* value)
|
||||
bool CommandLineArguments::PopulateVariable(
|
||||
CommandLineArgumentsCallbackStructure* cs, const char* value)
|
||||
{
|
||||
// Call the callback
|
||||
if ( cs->Callback )
|
||||
{
|
||||
if ( !cs->Callback(cs->Argument, value, cs->CallData) )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
if (cs->Callback) {
|
||||
if (!cs->Callback(cs->Argument, value, cs->CallData)) {
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value);
|
||||
if ( cs->Variable )
|
||||
{
|
||||
}
|
||||
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to "
|
||||
<< value);
|
||||
if (cs->Variable) {
|
||||
std::string var = "1";
|
||||
if ( value )
|
||||
{
|
||||
if (value) {
|
||||
var = value;
|
||||
}
|
||||
switch ( cs->VariableType )
|
||||
{
|
||||
case CommandLineArguments::INT_TYPE:
|
||||
this->PopulateVariable(static_cast<int*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<double*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<char**>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STL_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<std::string*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_INT_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STL_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<std::string>*>(cs->Variable), var);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << std::endl;
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
switch (cs->VariableType) {
|
||||
case CommandLineArguments::INT_TYPE:
|
||||
this->PopulateVariable(static_cast<int*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<double*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<char**>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STL_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<std::string*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable),
|
||||
var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_INT_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable),
|
||||
var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable),
|
||||
var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable),
|
||||
var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STL_STRING_TYPE:
|
||||
this->PopulateVariable(
|
||||
static_cast<std::vector<std::string>*>(cs->Variable), var);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Got unknown variable type: \"" << cs->VariableType
|
||||
<< "\"" << std::endl;
|
||||
this->Internals->LastArgument--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_CommandLineArguments_hxx
|
||||
#define @KWSYS_NAMESPACE@_CommandLineArguments_hxx
|
||||
|
||||
@@ -18,8 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
class CommandLineArgumentsInternal;
|
||||
struct CommandLineArgumentsCallbackStructure;
|
||||
@@ -41,28 +31,29 @@ struct CommandLineArgumentsCallbackStructure;
|
||||
* the argument is specified, the variable is set to the specified value casted
|
||||
* to the appropriate type. For boolean (NO_ARGUMENT), the value is "1".
|
||||
*
|
||||
* Both interfaces can be used at the same time.
|
||||
* Both interfaces can be used at the same time.
|
||||
*
|
||||
* Possible argument types are:
|
||||
* NO_ARGUMENT - The argument takes no value : --A
|
||||
* CONCAT_ARGUMENT - The argument takes value after no space : --Aval
|
||||
* SPACE_ARGUMENT - The argument takes value after space : --A val
|
||||
* SPACE_ARGUMENT - The argument takes value after space : --A val
|
||||
* EQUAL_ARGUMENT - The argument takes value after equal : --A=val
|
||||
* MULTI_ARGUMENT - The argument takes values after space : --A val1 val2 val3 ...
|
||||
* MULTI_ARGUMENT - The argument takes values after space : --A val1 val2
|
||||
* val3 ...
|
||||
*
|
||||
* Example use:
|
||||
*
|
||||
* kwsys::CommandLineArguments arg;
|
||||
* arg.Initialize(argc, argv);
|
||||
* typedef kwsys::CommandLineArguments argT;
|
||||
* arg.AddArgument("--something", argT::EQUAL_ARGUMENT, &some_variable,
|
||||
* arg.AddArgument("--something", argT::EQUAL_ARGUMENT, &some_variable,
|
||||
* "This is help string for --something");
|
||||
* if ( !arg.Parse() )
|
||||
* {
|
||||
* std::cerr << "Problem parsing arguments" << std::endl;
|
||||
* res = 1;
|
||||
* }
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments
|
||||
@@ -74,7 +65,8 @@ public:
|
||||
/**
|
||||
* Various argument types.
|
||||
*/
|
||||
enum ArgumentTypeEnum {
|
||||
enum ArgumentTypeEnum
|
||||
{
|
||||
NO_ARGUMENT,
|
||||
CONCAT_ARGUMENT,
|
||||
SPACE_ARGUMENT,
|
||||
@@ -86,27 +78,28 @@ public:
|
||||
* Various variable types. When using the variable interface, this specifies
|
||||
* what type the variable is.
|
||||
*/
|
||||
enum VariableTypeEnum {
|
||||
NO_VARIABLE_TYPE = 0, // The variable is not specified
|
||||
INT_TYPE, // The variable is integer (int)
|
||||
BOOL_TYPE, // The variable is boolean (bool)
|
||||
DOUBLE_TYPE, // The variable is float (double)
|
||||
STRING_TYPE, // The variable is string (char*)
|
||||
STL_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_INT_TYPE, // The variable is integer (int)
|
||||
VECTOR_BOOL_TYPE, // The variable is boolean (bool)
|
||||
VECTOR_DOUBLE_TYPE, // The variable is float (double)
|
||||
VECTOR_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_STL_STRING_TYPE, // The variable is string (char*)
|
||||
enum VariableTypeEnum
|
||||
{
|
||||
NO_VARIABLE_TYPE = 0, // The variable is not specified
|
||||
INT_TYPE, // The variable is integer (int)
|
||||
BOOL_TYPE, // The variable is boolean (bool)
|
||||
DOUBLE_TYPE, // The variable is float (double)
|
||||
STRING_TYPE, // The variable is string (char*)
|
||||
STL_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_INT_TYPE, // The variable is integer (int)
|
||||
VECTOR_BOOL_TYPE, // The variable is boolean (bool)
|
||||
VECTOR_DOUBLE_TYPE, // The variable is float (double)
|
||||
VECTOR_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_STL_STRING_TYPE, // The variable is string (char*)
|
||||
LAST_VARIABLE_TYPE
|
||||
};
|
||||
|
||||
/**
|
||||
* Prototypes for callbacks for callback interface.
|
||||
*/
|
||||
typedef int(*CallbackType)(const char* argument, const char* value,
|
||||
void* call_data);
|
||||
typedef int(*ErrorCallbackType)(const char* argument, void* client_data);
|
||||
typedef int (*CallbackType)(const char* argument, const char* value,
|
||||
void* call_data);
|
||||
typedef int (*ErrorCallbackType)(const char* argument, void* client_data);
|
||||
|
||||
/**
|
||||
* Initialize internal data structures. This should be called before parsing.
|
||||
@@ -133,24 +126,24 @@ public:
|
||||
* argument help specifies the help string used with this option. The
|
||||
* callback and call_data can be skipped.
|
||||
*/
|
||||
void AddCallback(const char* argument, ArgumentTypeEnum type,
|
||||
CallbackType callback, void* call_data, const char* help);
|
||||
void AddCallback(const char* argument, ArgumentTypeEnum type,
|
||||
CallbackType callback, void* call_data, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for argument which is going to set the variable to the
|
||||
* specified value. If the argument is specified, the option is casted to the
|
||||
* appropriate type.
|
||||
*/
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type, bool* variable,
|
||||
const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type, int* variable,
|
||||
const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
bool* variable, const char* help);
|
||||
double* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
int* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
double* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
char** variable, const char* help);
|
||||
char** variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::string* variable, const char* help);
|
||||
std::string* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for argument which is going to set the variable to the
|
||||
@@ -158,31 +151,31 @@ public:
|
||||
* appropriate type. This will handle the multi argument values.
|
||||
*/
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<bool>* variable, const char* help);
|
||||
std::vector<bool>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<int>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<double>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<char*>* variable, const char* help);
|
||||
std::vector<int>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<std::string>* variable, const char* help);
|
||||
std::vector<double>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<char*>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
std::vector<std::string>* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for boolean argument. The argument does not take any option
|
||||
* and if it is specified, the value of the variable is true/1, otherwise it
|
||||
* is false/0.
|
||||
*/
|
||||
void AddBooleanArgument(const char* argument,
|
||||
bool* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
int* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
double* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
char** variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
std::string* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument, bool* variable,
|
||||
const char* help);
|
||||
void AddBooleanArgument(const char* argument, int* variable,
|
||||
const char* help);
|
||||
void AddBooleanArgument(const char* argument, double* variable,
|
||||
const char* help);
|
||||
void AddBooleanArgument(const char* argument, char** variable,
|
||||
const char* help);
|
||||
void AddBooleanArgument(const char* argument, std::string* variable,
|
||||
const char* help);
|
||||
|
||||
/**
|
||||
* Set the callbacks for error handling.
|
||||
@@ -236,14 +229,14 @@ protected:
|
||||
|
||||
//! This is internal method that registers variable with argument
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
VariableTypeEnum vtype, void* variable, const char* help);
|
||||
VariableTypeEnum vtype, void* variable, const char* help);
|
||||
|
||||
bool GetMatchedArguments(std::vector<std::string>* matches,
|
||||
const std::string& arg);
|
||||
const std::string& arg);
|
||||
|
||||
//! Populate individual variables
|
||||
bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
|
||||
const char* value);
|
||||
const char* value);
|
||||
|
||||
//! Populate individual variables of type ...
|
||||
void PopulateVariable(bool* variable, const std::string& value);
|
||||
@@ -253,9 +246,12 @@ protected:
|
||||
void PopulateVariable(std::string* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<bool>* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<int>* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<double>* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<char*>* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<std::string>* variable, const std::string& value);
|
||||
void PopulateVariable(std::vector<double>* variable,
|
||||
const std::string& value);
|
||||
void PopulateVariable(std::vector<char*>* variable,
|
||||
const std::string& value);
|
||||
void PopulateVariable(std::vector<std::string>* variable,
|
||||
const std::string& value);
|
||||
|
||||
typedef CommandLineArgumentsInternal Internal;
|
||||
Internal* Internals;
|
||||
@@ -269,8 +265,3 @@ protected:
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+79
-88
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Configure_h
|
||||
#define @KWSYS_NAMESPACE@_Configure_h
|
||||
|
||||
@@ -16,22 +7,22 @@
|
||||
namespace. When not building a kwsys source file these macros are
|
||||
temporarily defined inside the headers that use them. */
|
||||
#if defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
|
||||
/* Disable some warnings inside kwsys source files. */
|
||||
#if defined(KWSYS_NAMESPACE)
|
||||
# if defined(__BORLANDC__)
|
||||
# pragma warn -8027 /* function not inlined. */
|
||||
# endif
|
||||
# if defined(__INTEL_COMPILER)
|
||||
# pragma warning (disable: 1572) /* floating-point equality test */
|
||||
# endif
|
||||
# if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 3970 /* pointer to int conversion */
|
||||
# pragma set woff 3968 /* 64 bit conversion */
|
||||
# endif
|
||||
#if defined(__BORLANDC__)
|
||||
#pragma warn - 8027 /* function not inlined. */
|
||||
#endif
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning(disable : 1572) /* floating-point equality test */
|
||||
#endif
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma set woff 3970 /* pointer to int conversion */
|
||||
#pragma set woff 3968 /* 64 bit conversion */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Whether kwsys namespace is "kwsys". */
|
||||
@@ -42,84 +33,84 @@
|
||||
|
||||
/* Whether Large File Support is available. */
|
||||
#if @KWSYS_NAMESPACE@_LFS_REQUESTED
|
||||
# define @KWSYS_NAMESPACE@_LFS_AVAILABLE @KWSYS_LFS_AVAILABLE@
|
||||
#define @KWSYS_NAMESPACE@_LFS_AVAILABLE @KWSYS_LFS_AVAILABLE@
|
||||
#endif
|
||||
|
||||
/* Setup Large File Support if requested. */
|
||||
#if @KWSYS_NAMESPACE@_LFS_REQUESTED
|
||||
/* Since LFS is requested this header must be included before system
|
||||
headers whether or not LFS is available. */
|
||||
# if 0 && (defined(_SYS_TYPES_H) || defined(_SYS_TYPES_INCLUDED))
|
||||
# error "@KWSYS_NAMESPACE@/Configure.h must be included before sys/types.h"
|
||||
# endif
|
||||
/* Enable the large file API if it is available. */
|
||||
# if @KWSYS_NAMESPACE@_LFS_AVAILABLE && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINES)
|
||||
# if !defined(_LARGEFILE_SOURCE) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE_SOURCE)
|
||||
# define _LARGEFILE_SOURCE
|
||||
# endif
|
||||
# if !defined(_LARGEFILE64_SOURCE) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE64_SOURCE)
|
||||
# define _LARGEFILE64_SOURCE
|
||||
# endif
|
||||
# if !defined(_LARGE_FILES) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGE_FILES)
|
||||
# define _LARGE_FILES
|
||||
# endif
|
||||
# if !defined(_FILE_OFFSET_BITS) && \
|
||||
!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
|
||||
/* Since LFS is requested this header must be included before system
|
||||
headers whether or not LFS is available. */
|
||||
#if 0 && (defined(_SYS_TYPES_H) || defined(_SYS_TYPES_INCLUDED))
|
||||
#error "@KWSYS_NAMESPACE@/Configure.h must be included before sys/types.h"
|
||||
#endif
|
||||
/* Enable the large file API if it is available. */
|
||||
#if @KWSYS_NAMESPACE@_LFS_AVAILABLE && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINES)
|
||||
#if !defined(_LARGEFILE_SOURCE) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE_SOURCE)
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGEFILE64_SOURCE) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE64_SOURCE)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGE_FILES) && \
|
||||
!defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGE_FILES)
|
||||
#define _LARGE_FILES
|
||||
#endif
|
||||
#if !defined(_FILE_OFFSET_BITS) && \
|
||||
!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
|
||||
|
||||
/* Setup the export macro. */
|
||||
#if @KWSYS_BUILD_SHARED@
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(@KWSYS_NAMESPACE@_EXPORTS)
|
||||
# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# elif __GNUC__ >= 4
|
||||
# define @KWSYS_NAMESPACE@_EXPORT __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define @KWSYS_NAMESPACE@_EXPORT
|
||||
# endif
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#if defined(@KWSYS_NAMESPACE@_EXPORTS)
|
||||
#define @KWSYS_NAMESPACE@_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define @KWSYS_NAMESPACE@_EXPORT
|
||||
#define @KWSYS_NAMESPACE@_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#elif __GNUC__ >= 4
|
||||
#define @KWSYS_NAMESPACE@_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#define @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
|
||||
/* Enable warnings that are off by default but are useful. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_ENABLE)
|
||||
# if defined(_MSC_VER)
|
||||
# pragma warning ( default : 4263 ) /* no override, call convention differs */
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(default : 4263) /* no override, call convention differs */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable warnings that are on by default but occur in valid code. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE)
|
||||
# if defined(_MSC_VER)
|
||||
# pragma warning (disable: 4097) /* typedef is synonym for class */
|
||||
# pragma warning (disable: 4127) /* conditional expression is constant */
|
||||
# pragma warning (disable: 4244) /* possible loss in conversion */
|
||||
# pragma warning (disable: 4251) /* missing DLL-interface */
|
||||
# pragma warning (disable: 4305) /* truncation from type1 to type2 */
|
||||
# pragma warning (disable: 4309) /* truncation of constant value */
|
||||
# pragma warning (disable: 4514) /* unreferenced inline function */
|
||||
# pragma warning (disable: 4706) /* assignment in conditional expression */
|
||||
# pragma warning (disable: 4710) /* function not inlined */
|
||||
# pragma warning (disable: 4786) /* identifier truncated in debug info */
|
||||
# endif
|
||||
# if defined(__BORLANDC__) && !defined(__cplusplus)
|
||||
/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
|
||||
unused parameter using "(param)" syntax (i.e. no cast to void). */
|
||||
# pragma warn -8019
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4097) /* typedef is synonym for class */
|
||||
#pragma warning(disable : 4127) /* conditional expression is constant */
|
||||
#pragma warning(disable : 4244) /* possible loss in conversion */
|
||||
#pragma warning(disable : 4251) /* missing DLL-interface */
|
||||
#pragma warning(disable : 4305) /* truncation from type1 to type2 */
|
||||
#pragma warning(disable : 4309) /* truncation of constant value */
|
||||
#pragma warning(disable : 4514) /* unreferenced inline function */
|
||||
#pragma warning(disable : 4706) /* assignment in conditional expression */
|
||||
#pragma warning(disable : 4710) /* function not inlined */
|
||||
#pragma warning(disable : 4786) /* identifier truncated in debug info */
|
||||
#endif
|
||||
#if defined(__BORLANDC__) && !defined(__cplusplus)
|
||||
/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
|
||||
unused parameter using "(param)" syntax (i.e. no cast to void). */
|
||||
#pragma warn - 8019
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* MSVC 6.0 in release mode will warn about code it produces with its
|
||||
@@ -127,10 +118,10 @@
|
||||
configuration. Real warnings will be revealed by a debug build or
|
||||
by other compilers. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE_BOGUS)
|
||||
# if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG)
|
||||
# pragma warning ( disable : 4701 ) /* Variable may be used uninitialized. */
|
||||
# pragma warning ( disable : 4702 ) /* Unreachable code. */
|
||||
# endif
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG)
|
||||
#pragma warning(disable : 4701) /* Variable may be used uninitialized. */
|
||||
#pragma warning(disable : 4702) /* Unreachable code. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Configure_hxx
|
||||
#define @KWSYS_NAMESPACE@_Configure_hxx
|
||||
|
||||
@@ -18,17 +9,19 @@
|
||||
/* Whether wstring is available. */
|
||||
#define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@
|
||||
/* Whether <ext/stdio_filebuf.h> is available. */
|
||||
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H @KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
|
||||
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \
|
||||
@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
|
||||
|
||||
/* If building a C++ file in kwsys itself, give the source file
|
||||
access to the macros without a configured namespace. */
|
||||
#if defined(KWSYS_NAMESPACE)
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsys @KWSYS_NAMESPACE@
|
||||
# endif
|
||||
# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# 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
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#define kwsys @KWSYS_NAMESPACE@
|
||||
#endif
|
||||
#define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+329
-318
@@ -1,354 +1,365 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx
|
||||
#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Encoding.hxx>
|
||||
#include <string>
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <streambuf>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# if __cplusplus >= 201103L
|
||||
# include <system_error>
|
||||
# endif
|
||||
#include <windows.h>
|
||||
#if __cplusplus >= 201103L
|
||||
#include <system_error>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
#if defined(_WIN32)
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT> >
|
||||
class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf :
|
||||
public std::basic_streambuf<CharT, Traits> {
|
||||
public:
|
||||
typedef typename Traits::int_type int_type;
|
||||
typedef typename Traits::char_type char_type;
|
||||
template <class CharT, class Traits = std::char_traits<CharT> >
|
||||
class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf
|
||||
: public std::basic_streambuf<CharT, Traits>
|
||||
{
|
||||
public:
|
||||
typedef typename Traits::int_type int_type;
|
||||
typedef typename Traits::char_type char_type;
|
||||
|
||||
class Manager {
|
||||
public:
|
||||
Manager(std::basic_ios<CharT, Traits> &ios, const bool err = false)
|
||||
: m_consolebuf(0)
|
||||
{
|
||||
m_ios = &ios;
|
||||
try {
|
||||
m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
|
||||
m_streambuf = m_ios->rdbuf(m_consolebuf);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
std::cerr << "Failed to create ConsoleBuf!" << std::endl
|
||||
<< ex.what() << std::endl;
|
||||
};
|
||||
}
|
||||
|
||||
~Manager()
|
||||
{
|
||||
if (m_consolebuf) {
|
||||
delete m_consolebuf;
|
||||
m_ios->rdbuf(m_streambuf);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::basic_ios<CharT, Traits> *m_ios;
|
||||
std::basic_streambuf<CharT, Traits> *m_streambuf;
|
||||
BasicConsoleBuf<CharT, Traits> *m_consolebuf;
|
||||
class Manager
|
||||
{
|
||||
public:
|
||||
Manager(std::basic_ios<CharT, Traits>& ios, const bool err = false)
|
||||
: m_consolebuf(0)
|
||||
{
|
||||
m_ios = &ios;
|
||||
try {
|
||||
m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
|
||||
m_streambuf = m_ios->rdbuf(m_consolebuf);
|
||||
} catch (const std::runtime_error& ex) {
|
||||
std::cerr << "Failed to create ConsoleBuf!" << std::endl
|
||||
<< ex.what() << std::endl;
|
||||
};
|
||||
}
|
||||
|
||||
BasicConsoleBuf(const bool err = false) :
|
||||
flush_on_newline(true),
|
||||
input_pipe_codepage(0),
|
||||
output_pipe_codepage(0),
|
||||
input_file_codepage(CP_UTF8),
|
||||
output_file_codepage(CP_UTF8),
|
||||
m_consolesCodepage(0)
|
||||
{
|
||||
m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
|
||||
checkHandle(true, "STD_INPUT_HANDLE");
|
||||
if (!setActiveInputCodepage()) {
|
||||
throw std::runtime_error("setActiveInputCodepage failed!");
|
||||
}
|
||||
m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) :
|
||||
::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
|
||||
if (!setActiveOutputCodepage()) {
|
||||
throw std::runtime_error("setActiveOutputCodepage failed!");
|
||||
}
|
||||
_setg();
|
||||
_setp();
|
||||
~Manager()
|
||||
{
|
||||
if (m_consolebuf) {
|
||||
delete m_consolebuf;
|
||||
m_ios->rdbuf(m_streambuf);
|
||||
}
|
||||
}
|
||||
|
||||
~BasicConsoleBuf() throw()
|
||||
{
|
||||
sync();
|
||||
}
|
||||
private:
|
||||
std::basic_ios<CharT, Traits>* m_ios;
|
||||
std::basic_streambuf<CharT, Traits>* m_streambuf;
|
||||
BasicConsoleBuf<CharT, Traits>* m_consolebuf;
|
||||
};
|
||||
|
||||
bool activateCodepageChange()
|
||||
{
|
||||
return setActiveInputCodepage() && setActiveOutputCodepage();
|
||||
}
|
||||
BasicConsoleBuf(const bool err = false)
|
||||
: flush_on_newline(true)
|
||||
, input_pipe_codepage(0)
|
||||
, output_pipe_codepage(0)
|
||||
, input_file_codepage(CP_UTF8)
|
||||
, output_file_codepage(CP_UTF8)
|
||||
, m_consolesCodepage(0)
|
||||
{
|
||||
m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
|
||||
checkHandle(true, "STD_INPUT_HANDLE");
|
||||
if (!setActiveInputCodepage()) {
|
||||
throw std::runtime_error("setActiveInputCodepage failed!");
|
||||
}
|
||||
m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE)
|
||||
: ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
|
||||
if (!setActiveOutputCodepage()) {
|
||||
throw std::runtime_error("setActiveOutputCodepage failed!");
|
||||
}
|
||||
_setg();
|
||||
_setp();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int sync() {
|
||||
bool success = true;
|
||||
if (m_hInput && m_isConsoleInput &&
|
||||
::FlushConsoleInputBuffer(m_hInput) == 0) {
|
||||
success = false;
|
||||
~BasicConsoleBuf() throw() { sync(); }
|
||||
|
||||
bool activateCodepageChange()
|
||||
{
|
||||
return setActiveInputCodepage() && setActiveOutputCodepage();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int sync()
|
||||
{
|
||||
bool success = true;
|
||||
if (m_hInput && m_isConsoleInput &&
|
||||
::FlushConsoleInputBuffer(m_hInput) == 0) {
|
||||
success = false;
|
||||
}
|
||||
if (m_hOutput && !m_obuffer.empty()) {
|
||||
const std::wstring wbuffer = getBuffer(m_obuffer);
|
||||
if (m_isConsoleOutput) {
|
||||
DWORD charsWritten;
|
||||
success =
|
||||
::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(),
|
||||
&charsWritten, NULL) == 0
|
||||
? false
|
||||
: true;
|
||||
} else {
|
||||
DWORD bytesWritten;
|
||||
std::string buffer;
|
||||
success = encodeOutputBuffer(wbuffer, buffer);
|
||||
if (success) {
|
||||
success = ::WriteFile(m_hOutput, buffer.c_str(),
|
||||
(DWORD)buffer.size(), &bytesWritten, NULL) == 0
|
||||
? false
|
||||
: true;
|
||||
}
|
||||
if (m_hOutput && !m_obuffer.empty()) {
|
||||
const std::wstring wbuffer = getBuffer(m_obuffer);
|
||||
if (m_isConsoleOutput) {
|
||||
DWORD charsWritten;
|
||||
success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(),
|
||||
(DWORD)wbuffer.size(), &charsWritten,
|
||||
NULL) == 0 ? false : true;
|
||||
} else {
|
||||
DWORD bytesWritten;
|
||||
std::string buffer;
|
||||
success = encodeOutputBuffer(wbuffer, buffer);
|
||||
if (success) {
|
||||
success = ::WriteFile(m_hOutput, buffer.c_str(),
|
||||
(DWORD)buffer.size(), &bytesWritten,
|
||||
NULL) == 0 ? false : true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_ibuffer.clear();
|
||||
m_obuffer.clear();
|
||||
_setg();
|
||||
_setp();
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
}
|
||||
m_ibuffer.clear();
|
||||
m_obuffer.clear();
|
||||
_setg();
|
||||
_setp();
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
|
||||
virtual int_type underflow() {
|
||||
if (this->gptr() >= this->egptr()) {
|
||||
if (!m_hInput) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
if (m_isConsoleInput) {
|
||||
wchar_t wbuffer[128];
|
||||
DWORD charsRead;
|
||||
if (::ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])) - 1,
|
||||
&charsRead, NULL) == 0 || charsRead == 0) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
wbuffer[charsRead] = L'\0';
|
||||
setBuffer(wbuffer, m_ibuffer);
|
||||
} else {
|
||||
std::wstring totalBuffer;
|
||||
std::wstring wbuffer;
|
||||
char buffer[128];
|
||||
DWORD bytesRead;
|
||||
while (::ReadFile(m_hInput, buffer, (sizeof(buffer) / sizeof(buffer[0])) - 1,
|
||||
&bytesRead, NULL) == 0) {
|
||||
if (::GetLastError() == ERROR_MORE_DATA) {
|
||||
buffer[bytesRead] = '\0';
|
||||
if (decodeInputBuffer(buffer, wbuffer)) {
|
||||
totalBuffer += wbuffer;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
buffer[bytesRead] = '\0';
|
||||
if (!decodeInputBuffer(buffer, wbuffer)) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
totalBuffer += wbuffer;
|
||||
setBuffer(totalBuffer, m_ibuffer);
|
||||
}
|
||||
_setg();
|
||||
}
|
||||
return Traits::to_int_type(*this->gptr());
|
||||
}
|
||||
|
||||
virtual int_type overflow(int_type ch = Traits::eof()) {
|
||||
if (!Traits::eq_int_type(ch, Traits::eof())) {
|
||||
char_type chr = Traits::to_char_type(ch);
|
||||
m_obuffer += chr;
|
||||
if ((flush_on_newline && Traits::eq(chr, '\n')) ||
|
||||
Traits::eq_int_type(ch, 0x00)) {
|
||||
sync();
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
sync();
|
||||
virtual int_type underflow()
|
||||
{
|
||||
if (this->gptr() >= this->egptr()) {
|
||||
if (!m_hInput) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
|
||||
public:
|
||||
bool flush_on_newline;
|
||||
UINT input_pipe_codepage;
|
||||
UINT output_pipe_codepage;
|
||||
UINT input_file_codepage;
|
||||
UINT output_file_codepage;
|
||||
|
||||
private:
|
||||
HANDLE m_hInput;
|
||||
HANDLE m_hOutput;
|
||||
std::basic_string<char_type> m_ibuffer;
|
||||
std::basic_string<char_type> m_obuffer;
|
||||
bool m_isConsoleInput;
|
||||
bool m_isConsoleOutput;
|
||||
UINT m_activeInputCodepage;
|
||||
UINT m_activeOutputCodepage;
|
||||
UINT m_consolesCodepage;
|
||||
void checkHandle(bool input, std::string handleName) {
|
||||
if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
|
||||
(!input && m_hOutput == INVALID_HANDLE_VALUE)) {
|
||||
std::string errmsg = "GetStdHandle(" + handleName +
|
||||
") returned INVALID_HANDLE_VALUE";
|
||||
#if __cplusplus >= 201103L
|
||||
throw std::system_error(::GetLastError(),
|
||||
std::system_category(), errmsg);
|
||||
#else
|
||||
throw std::runtime_error(errmsg);
|
||||
#endif
|
||||
if (m_isConsoleInput) {
|
||||
wchar_t wbuffer[128];
|
||||
DWORD charsRead;
|
||||
if (::ReadConsoleW(m_hInput, wbuffer,
|
||||
(sizeof(wbuffer) / sizeof(wbuffer[0])) - 1,
|
||||
&charsRead, NULL) == 0 ||
|
||||
charsRead == 0) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
}
|
||||
UINT getConsolesCodepage() {
|
||||
if (!m_consolesCodepage) {
|
||||
m_consolesCodepage = GetConsoleCP();
|
||||
if (!m_consolesCodepage) {
|
||||
m_consolesCodepage = GetACP();
|
||||
wbuffer[charsRead] = L'\0';
|
||||
setBuffer(wbuffer, m_ibuffer);
|
||||
} else {
|
||||
std::wstring totalBuffer;
|
||||
std::wstring wbuffer;
|
||||
char buffer[128];
|
||||
DWORD bytesRead;
|
||||
while (::ReadFile(m_hInput, buffer,
|
||||
(sizeof(buffer) / sizeof(buffer[0])) - 1, &bytesRead,
|
||||
NULL) == 0) {
|
||||
if (::GetLastError() == ERROR_MORE_DATA) {
|
||||
buffer[bytesRead] = '\0';
|
||||
if (decodeInputBuffer(buffer, wbuffer)) {
|
||||
totalBuffer += wbuffer;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
return m_consolesCodepage;
|
||||
}
|
||||
bool setActiveInputCodepage() {
|
||||
m_isConsoleInput = false;
|
||||
switch (GetFileType(m_hInput)) {
|
||||
case FILE_TYPE_DISK:
|
||||
m_activeInputCodepage = input_file_codepage;
|
||||
break;
|
||||
case FILE_TYPE_CHAR:
|
||||
// Check for actual console.
|
||||
DWORD consoleMode;
|
||||
m_isConsoleInput = GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true;
|
||||
if (m_isConsoleInput) {
|
||||
break;
|
||||
}
|
||||
case FILE_TYPE_PIPE:
|
||||
m_activeInputCodepage = input_pipe_codepage;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
buffer[bytesRead] = '\0';
|
||||
if (!decodeInputBuffer(buffer, wbuffer)) {
|
||||
_setg(true);
|
||||
return Traits::eof();
|
||||
}
|
||||
if (!m_isConsoleInput && m_activeInputCodepage == 0) {
|
||||
m_activeInputCodepage = getConsolesCodepage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool setActiveOutputCodepage() {
|
||||
m_isConsoleOutput = false;
|
||||
switch (GetFileType(m_hOutput)) {
|
||||
case FILE_TYPE_DISK:
|
||||
m_activeOutputCodepage = output_file_codepage;
|
||||
break;
|
||||
case FILE_TYPE_CHAR:
|
||||
// Check for actual console.
|
||||
DWORD consoleMode;
|
||||
m_isConsoleOutput = GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true;
|
||||
if (m_isConsoleOutput) {
|
||||
break;
|
||||
}
|
||||
case FILE_TYPE_PIPE:
|
||||
m_activeOutputCodepage = output_pipe_codepage;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
|
||||
m_activeOutputCodepage = getConsolesCodepage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void _setg(bool empty = false) {
|
||||
if (!empty) {
|
||||
this->setg((char_type *)m_ibuffer.data(),
|
||||
(char_type *)m_ibuffer.data(),
|
||||
(char_type *)m_ibuffer.data() + m_ibuffer.size());
|
||||
} else {
|
||||
this->setg((char_type *)m_ibuffer.data(),
|
||||
(char_type *)m_ibuffer.data() + m_ibuffer.size(),
|
||||
(char_type *)m_ibuffer.data() + m_ibuffer.size());
|
||||
}
|
||||
}
|
||||
void _setp() {
|
||||
this->setp((char_type *)m_obuffer.data(),
|
||||
(char_type *)m_obuffer.data() + m_obuffer.size());
|
||||
}
|
||||
bool encodeOutputBuffer(const std::wstring wbuffer,
|
||||
std::string &buffer) {
|
||||
const int length = WideCharToMultiByte(m_activeOutputCodepage, 0,
|
||||
wbuffer.c_str(),
|
||||
(int)wbuffer.size(), NULL, 0,
|
||||
NULL, NULL);
|
||||
char *buf = new char[length + 1];
|
||||
const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0,
|
||||
wbuffer.c_str(),
|
||||
(int)wbuffer.size(), buf,
|
||||
length, NULL, NULL) > 0
|
||||
? true : false;
|
||||
buf[length] = '\0';
|
||||
buffer = buf;
|
||||
delete[] buf;
|
||||
return success;
|
||||
}
|
||||
bool decodeInputBuffer(const char *buffer, std::wstring &wbuffer) {
|
||||
int actualCodepage = m_activeInputCodepage;
|
||||
const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
|
||||
if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) {
|
||||
// PowerShell uses UTF-8 with BOM for pipes
|
||||
actualCodepage = CP_UTF8;
|
||||
buffer += sizeof(BOM_UTF8);
|
||||
}
|
||||
const int wlength = MultiByteToWideChar(actualCodepage, 0, buffer,
|
||||
-1, NULL, 0);
|
||||
wchar_t *wbuf = new wchar_t[wlength];
|
||||
const bool success = MultiByteToWideChar(actualCodepage, 0, buffer,
|
||||
-1, wbuf, wlength) > 0
|
||||
? true : false;
|
||||
wbuffer = wbuf;
|
||||
delete[] wbuf;
|
||||
return success;
|
||||
}
|
||||
std::wstring getBuffer(const std::basic_string<char> buffer) {
|
||||
return Encoding::ToWide(buffer);
|
||||
}
|
||||
std::wstring getBuffer(const std::basic_string<wchar_t> buffer) {
|
||||
return buffer;
|
||||
}
|
||||
void setBuffer(const std::wstring wbuffer,
|
||||
std::basic_string<char> &target) {
|
||||
target = Encoding::ToNarrow(wbuffer);
|
||||
}
|
||||
void setBuffer(const std::wstring wbuffer,
|
||||
std::basic_string<wchar_t> &target) {
|
||||
target = wbuffer;
|
||||
totalBuffer += wbuffer;
|
||||
setBuffer(totalBuffer, m_ibuffer);
|
||||
}
|
||||
_setg();
|
||||
}
|
||||
return Traits::to_int_type(*this->gptr());
|
||||
}
|
||||
|
||||
}; // BasicConsoleBuf class
|
||||
virtual int_type overflow(int_type ch = Traits::eof())
|
||||
{
|
||||
if (!Traits::eq_int_type(ch, Traits::eof())) {
|
||||
char_type chr = Traits::to_char_type(ch);
|
||||
m_obuffer += chr;
|
||||
if ((flush_on_newline && Traits::eq(chr, '\n')) ||
|
||||
Traits::eq_int_type(ch, 0x00)) {
|
||||
sync();
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
sync();
|
||||
return Traits::eof();
|
||||
}
|
||||
|
||||
typedef BasicConsoleBuf<char> ConsoleBuf;
|
||||
typedef BasicConsoleBuf<wchar_t> WConsoleBuf;
|
||||
public:
|
||||
bool flush_on_newline;
|
||||
UINT input_pipe_codepage;
|
||||
UINT output_pipe_codepage;
|
||||
UINT input_file_codepage;
|
||||
UINT output_file_codepage;
|
||||
|
||||
private:
|
||||
HANDLE m_hInput;
|
||||
HANDLE m_hOutput;
|
||||
std::basic_string<char_type> m_ibuffer;
|
||||
std::basic_string<char_type> m_obuffer;
|
||||
bool m_isConsoleInput;
|
||||
bool m_isConsoleOutput;
|
||||
UINT m_activeInputCodepage;
|
||||
UINT m_activeOutputCodepage;
|
||||
UINT m_consolesCodepage;
|
||||
void checkHandle(bool input, std::string handleName)
|
||||
{
|
||||
if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
|
||||
(!input && m_hOutput == INVALID_HANDLE_VALUE)) {
|
||||
std::string errmsg =
|
||||
"GetStdHandle(" + handleName + ") returned INVALID_HANDLE_VALUE";
|
||||
#if __cplusplus >= 201103L
|
||||
throw std::system_error(::GetLastError(), std::system_category(),
|
||||
errmsg);
|
||||
#else
|
||||
throw std::runtime_error(errmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
UINT getConsolesCodepage()
|
||||
{
|
||||
if (!m_consolesCodepage) {
|
||||
m_consolesCodepage = GetConsoleCP();
|
||||
if (!m_consolesCodepage) {
|
||||
m_consolesCodepage = GetACP();
|
||||
}
|
||||
}
|
||||
return m_consolesCodepage;
|
||||
}
|
||||
bool setActiveInputCodepage()
|
||||
{
|
||||
m_isConsoleInput = false;
|
||||
switch (GetFileType(m_hInput)) {
|
||||
case FILE_TYPE_DISK:
|
||||
m_activeInputCodepage = input_file_codepage;
|
||||
break;
|
||||
case FILE_TYPE_CHAR:
|
||||
// Check for actual console.
|
||||
DWORD consoleMode;
|
||||
m_isConsoleInput =
|
||||
GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true;
|
||||
if (m_isConsoleInput) {
|
||||
break;
|
||||
}
|
||||
case FILE_TYPE_PIPE:
|
||||
m_activeInputCodepage = input_pipe_codepage;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!m_isConsoleInput && m_activeInputCodepage == 0) {
|
||||
m_activeInputCodepage = getConsolesCodepage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool setActiveOutputCodepage()
|
||||
{
|
||||
m_isConsoleOutput = false;
|
||||
switch (GetFileType(m_hOutput)) {
|
||||
case FILE_TYPE_DISK:
|
||||
m_activeOutputCodepage = output_file_codepage;
|
||||
break;
|
||||
case FILE_TYPE_CHAR:
|
||||
// Check for actual console.
|
||||
DWORD consoleMode;
|
||||
m_isConsoleOutput =
|
||||
GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true;
|
||||
if (m_isConsoleOutput) {
|
||||
break;
|
||||
}
|
||||
case FILE_TYPE_PIPE:
|
||||
m_activeOutputCodepage = output_pipe_codepage;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
|
||||
m_activeOutputCodepage = getConsolesCodepage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void _setg(bool empty = false)
|
||||
{
|
||||
if (!empty) {
|
||||
this->setg((char_type*)m_ibuffer.data(), (char_type*)m_ibuffer.data(),
|
||||
(char_type*)m_ibuffer.data() + m_ibuffer.size());
|
||||
} else {
|
||||
this->setg((char_type*)m_ibuffer.data(),
|
||||
(char_type*)m_ibuffer.data() + m_ibuffer.size(),
|
||||
(char_type*)m_ibuffer.data() + m_ibuffer.size());
|
||||
}
|
||||
}
|
||||
void _setp()
|
||||
{
|
||||
this->setp((char_type*)m_obuffer.data(),
|
||||
(char_type*)m_obuffer.data() + m_obuffer.size());
|
||||
}
|
||||
bool encodeOutputBuffer(const std::wstring wbuffer, std::string& buffer)
|
||||
{
|
||||
const int length =
|
||||
WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
|
||||
(int)wbuffer.size(), NULL, 0, NULL, NULL);
|
||||
char* buf = new char[length + 1];
|
||||
const bool success =
|
||||
WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
|
||||
(int)wbuffer.size(), buf, length, NULL, NULL) > 0
|
||||
? true
|
||||
: false;
|
||||
buf[length] = '\0';
|
||||
buffer = buf;
|
||||
delete[] buf;
|
||||
return success;
|
||||
}
|
||||
bool decodeInputBuffer(const char* buffer, std::wstring& wbuffer)
|
||||
{
|
||||
int actualCodepage = m_activeInputCodepage;
|
||||
const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
|
||||
if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) {
|
||||
// PowerShell uses UTF-8 with BOM for pipes
|
||||
actualCodepage = CP_UTF8;
|
||||
buffer += sizeof(BOM_UTF8);
|
||||
}
|
||||
const int wlength =
|
||||
MultiByteToWideChar(actualCodepage, 0, buffer, -1, NULL, 0);
|
||||
wchar_t* wbuf = new wchar_t[wlength];
|
||||
const bool success =
|
||||
MultiByteToWideChar(actualCodepage, 0, buffer, -1, wbuf, wlength) > 0
|
||||
? true
|
||||
: false;
|
||||
wbuffer = wbuf;
|
||||
delete[] wbuf;
|
||||
return success;
|
||||
}
|
||||
std::wstring getBuffer(const std::basic_string<char> buffer)
|
||||
{
|
||||
return Encoding::ToWide(buffer);
|
||||
}
|
||||
std::wstring getBuffer(const std::basic_string<wchar_t> buffer)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
void setBuffer(const std::wstring wbuffer, std::basic_string<char>& target)
|
||||
{
|
||||
target = Encoding::ToNarrow(wbuffer);
|
||||
}
|
||||
void setBuffer(const std::wstring wbuffer,
|
||||
std::basic_string<wchar_t>& target)
|
||||
{
|
||||
target = wbuffer;
|
||||
}
|
||||
|
||||
}; // BasicConsoleBuf class
|
||||
|
||||
typedef BasicConsoleBuf<char> ConsoleBuf;
|
||||
typedef BasicConsoleBuf<wchar_t> WConsoleBuf;
|
||||
|
||||
#endif
|
||||
} // KWSYS_NAMESPACE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
Copyright 2000-2016 Kitware, Inc. and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -13,10 +13,9 @@ are met:
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
nor the names of their contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
* Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
@@ -29,3 +28,11 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The following individuals and institutions are among the Contributors:
|
||||
|
||||
* Insight Software Consortium <insightsoftwareconsortium.org>
|
||||
|
||||
See version control history for details of individual contributions.
|
||||
+56
-84
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Directory.hxx)
|
||||
|
||||
@@ -19,16 +10,15 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Directory.hxx.in"
|
||||
# include "Configure.hxx.in"
|
||||
# include "Encoding.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#include "Directory.hxx.in"
|
||||
#include "Encoding.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class DirectoryInternals
|
||||
@@ -62,10 +52,9 @@ unsigned long Directory::GetNumberOfFiles() const
|
||||
//----------------------------------------------------------------------------
|
||||
const char* Directory::GetFile(unsigned long dindex) const
|
||||
{
|
||||
if ( dindex >= this->Internal->Files.size() )
|
||||
{
|
||||
if (dindex >= this->Internal->Files.size()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return this->Internal->Files[dindex].c_str();
|
||||
}
|
||||
|
||||
@@ -88,9 +77,10 @@ void Directory::Clear()
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -99,15 +89,14 @@ void Directory::Clear()
|
||||
|
||||
// Wide function names can vary depending on compiler:
|
||||
#ifdef __BORLANDC__
|
||||
# define _wfindfirst_func __wfindfirst
|
||||
# define _wfindnext_func __wfindnext
|
||||
#define _wfindfirst_func __wfindfirst
|
||||
#define _wfindnext_func __wfindnext
|
||||
#else
|
||||
# define _wfindfirst_func _wfindfirst
|
||||
# define _wfindnext_func _wfindnext
|
||||
#define _wfindfirst_func _wfindfirst
|
||||
#define _wfindnext_func _wfindnext
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
bool Directory::Load(const std::string& name)
|
||||
{
|
||||
@@ -120,42 +109,34 @@ bool Directory::Load(const std::string& name)
|
||||
#endif
|
||||
char* buf;
|
||||
size_t n = name.size();
|
||||
if ( *name.rbegin() == '/' || *name.rbegin() == '\\' )
|
||||
{
|
||||
if (*name.rbegin() == '/' || *name.rbegin() == '\\') {
|
||||
buf = new char[n + 1 + 1];
|
||||
sprintf(buf, "%s*", name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Make sure the slashes in the wildcard suffix are consistent with the
|
||||
// rest of the path
|
||||
buf = new char[n + 2 + 1];
|
||||
if ( name.find('\\') != name.npos )
|
||||
{
|
||||
if (name.find('\\') != name.npos) {
|
||||
sprintf(buf, "%s\\*", name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sprintf(buf, "%s/*", name.c_str());
|
||||
}
|
||||
}
|
||||
struct _wfinddata_t data; // data of current file
|
||||
}
|
||||
struct _wfinddata_t data; // data of current file
|
||||
|
||||
// Now put them into the file array
|
||||
srchHandle = _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
|
||||
delete [] buf;
|
||||
srchHandle =
|
||||
_wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
|
||||
delete[] buf;
|
||||
|
||||
if ( srchHandle == -1 )
|
||||
{
|
||||
if (srchHandle == -1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through names
|
||||
do
|
||||
{
|
||||
do {
|
||||
this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
|
||||
}
|
||||
while ( _wfindnext_func(srchHandle, &data) != -1 );
|
||||
} while (_wfindnext_func(srchHandle, &data) != -1);
|
||||
this->Internal->Path = name;
|
||||
return _findclose(srchHandle) != -1;
|
||||
}
|
||||
@@ -170,34 +151,29 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
|
||||
#endif
|
||||
char* buf;
|
||||
size_t n = name.size();
|
||||
if ( *name.rbegin() == '/' )
|
||||
{
|
||||
if (*name.rbegin() == '/') {
|
||||
buf = new char[n + 1 + 1];
|
||||
sprintf(buf, "%s*", name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
buf = new char[n + 2 + 1];
|
||||
sprintf(buf, "%s/*", name.c_str());
|
||||
}
|
||||
struct _wfinddata_t data; // data of current file
|
||||
}
|
||||
struct _wfinddata_t data; // data of current file
|
||||
|
||||
// Now put them into the file array
|
||||
srchHandle = _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
|
||||
delete [] buf;
|
||||
srchHandle =
|
||||
_wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
|
||||
delete[] buf;
|
||||
|
||||
if ( srchHandle == -1 )
|
||||
{
|
||||
if (srchHandle == -1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through names
|
||||
unsigned long count = 0;
|
||||
do
|
||||
{
|
||||
do {
|
||||
count++;
|
||||
}
|
||||
while ( _wfindnext_func(srchHandle, &data) != -1 );
|
||||
} while (_wfindnext_func(srchHandle, &data) != -1);
|
||||
_findclose(srchHandle);
|
||||
return count;
|
||||
}
|
||||
@@ -209,6 +185,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
|
||||
// Now the POSIX style directory access
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
// PGI with glibc has trouble with dirent and large file support:
|
||||
@@ -216,33 +193,30 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
|
||||
// p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
|
||||
// Work around the problem by mapping dirent the same way as readdir.
|
||||
#if defined(__PGI) && defined(__GLIBC__)
|
||||
# define kwsys_dirent_readdir dirent
|
||||
# define kwsys_dirent_readdir64 dirent64
|
||||
# define kwsys_dirent kwsys_dirent_lookup(readdir)
|
||||
# define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x)
|
||||
# define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x
|
||||
#define kwsys_dirent_readdir dirent
|
||||
#define kwsys_dirent_readdir64 dirent64
|
||||
#define kwsys_dirent kwsys_dirent_lookup(readdir)
|
||||
#define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x)
|
||||
#define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x
|
||||
#else
|
||||
# define kwsys_dirent dirent
|
||||
#define kwsys_dirent dirent
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
bool Directory::Load(const std::string& name)
|
||||
{
|
||||
this->Clear();
|
||||
|
||||
|
||||
DIR* dir = opendir(name.c_str());
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
if (!dir) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) )
|
||||
{
|
||||
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
|
||||
this->Internal->Files.push_back(d->d_name);
|
||||
}
|
||||
}
|
||||
this->Internal->Path = name;
|
||||
closedir(dir);
|
||||
return 1;
|
||||
@@ -252,16 +226,14 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
|
||||
{
|
||||
DIR* dir = opendir(name.c_str());
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
if (!dir) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long count = 0;
|
||||
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) )
|
||||
{
|
||||
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Directory_hxx
|
||||
#define @KWSYS_NAMESPACE@_Directory_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
class DirectoryInternals;
|
||||
|
||||
@@ -72,9 +63,9 @@ private:
|
||||
// Private implementation details.
|
||||
DirectoryInternals* Internal;
|
||||
|
||||
Directory(const Directory&); // Not implemented.
|
||||
void operator=(const Directory&); // Not implemented.
|
||||
}; // End Class: Directory
|
||||
Directory(const Directory&); // Not implemented.
|
||||
void operator=(const Directory&); // Not implemented.
|
||||
}; // End Class: Directory
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
|
||||
+98
-127
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(DynamicLoader.hxx)
|
||||
|
||||
@@ -17,8 +8,8 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "DynamicLoader.hxx.in"
|
||||
# include "Configure.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#include "DynamicLoader.hxx.in"
|
||||
#endif
|
||||
|
||||
// This file is actually 3 different implementations.
|
||||
@@ -32,15 +23,15 @@
|
||||
// ---------------------------------------------------------------
|
||||
// 1. Implementation for HPUX machines
|
||||
#ifdef __hpux
|
||||
#include <errno.h>
|
||||
#include <dl.h>
|
||||
#include <errno.h>
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
|
||||
}
|
||||
@@ -48,25 +39,25 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libna
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
if (!lib)
|
||||
{
|
||||
if (!lib) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return !shl_unload(lib);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::SymbolPointer
|
||||
DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
{
|
||||
void* addr;
|
||||
int status;
|
||||
|
||||
/* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
|
||||
* TYPE_DATA Look for a symbol in the data segment (for example, variables).
|
||||
* TYPE_DATA Look for a symbol in the data segment (for example,
|
||||
* variables).
|
||||
* TYPE_UNDEFINED Look for any symbol.
|
||||
*/
|
||||
status = shl_findsym (&lib, sym.c_str(), TYPE_UNDEFINED, &addr);
|
||||
status = shl_findsym(&lib, sym.c_str(), TYPE_UNDEFINED, &addr);
|
||||
void* result = (status < 0) ? (void*)0 : addr;
|
||||
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
@@ -88,12 +79,9 @@ const char* DynamicLoader::LastError()
|
||||
* The specified handle is invalid.
|
||||
*/
|
||||
|
||||
if( errno == ENOEXEC
|
||||
|| errno == ENOSYM
|
||||
|| errno == EINVAL )
|
||||
{
|
||||
if (errno == ENOEXEC || errno == ENOSYM || errno == EINVAL) {
|
||||
return strerror(errno);
|
||||
}
|
||||
}
|
||||
// else
|
||||
return 0;
|
||||
}
|
||||
@@ -102,38 +90,37 @@ const char* DynamicLoader::LastError()
|
||||
|
||||
#endif //__hpux
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// 2. Implementation for Mac OS X 10.2.x and earlier
|
||||
#ifdef __APPLE__
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
|
||||
#include <string.h> // for strlen
|
||||
#include <mach-o/dyld.h>
|
||||
#include <string.h> // for strlen
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
NSObjectFileImageReturnCode rc;
|
||||
NSObjectFileImage image = 0;
|
||||
|
||||
rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image);
|
||||
// rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
|
||||
if( rc != NSObjectFileImageSuccess )
|
||||
{
|
||||
if (rc != NSObjectFileImageSuccess) {
|
||||
return 0;
|
||||
}
|
||||
NSModule handle = NSLinkModule(image, libname.c_str(),
|
||||
NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
NSModule handle =
|
||||
NSLinkModule(image, libname.c_str(), NSLINKMODULE_OPTION_BINDNOW |
|
||||
NSLINKMODULE_OPTION_RETURN_ON_ERROR);
|
||||
NSDestroyObjectFileImage(image);
|
||||
return handle;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
// NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
|
||||
// With this option the memory for the module is not deallocated
|
||||
@@ -148,18 +135,17 @@ int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
|
||||
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
{
|
||||
void *result=0;
|
||||
void* result = 0;
|
||||
// Need to prepend symbols with '_' on Apple-gcc compilers
|
||||
size_t len = sym.size();
|
||||
char *rsym = new char[len + 1 + 1];
|
||||
char* rsym = new char[len + 1 + 1];
|
||||
strcpy(rsym, "_");
|
||||
strcat(rsym+1, sym.c_str());
|
||||
strcat(rsym + 1, sym.c_str());
|
||||
|
||||
NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
|
||||
if(symbol)
|
||||
{
|
||||
if (symbol) {
|
||||
result = NSAddressOfSymbol(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] rsym;
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
@@ -183,19 +169,19 @@ const char* DynamicLoader::LastError()
|
||||
#include <windows.h>
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname)
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
DynamicLoader::LibraryHandle lh;
|
||||
int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0);
|
||||
wchar_t* wchars = new wchar_t[length+1];
|
||||
wchar_t* wchars = new wchar_t[length + 1];
|
||||
wchars[0] = '\0';
|
||||
MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length);
|
||||
lh = LoadLibraryW(wchars);
|
||||
delete [] wchars;
|
||||
delete[] wchars;
|
||||
return lh;
|
||||
}
|
||||
|
||||
@@ -231,21 +217,21 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
//
|
||||
// Note that the "@X" part of the name above is the total size (in
|
||||
// bytes) of the arguments on the stack.
|
||||
void *result;
|
||||
void* result;
|
||||
#if defined(__BORLANDC__) || defined(__WATCOMC__)
|
||||
// Need to prepend symbols with '_'
|
||||
size_t len = sym.size();
|
||||
char *rsym = new char[len + 1 + 1];
|
||||
char* rsym = new char[len + 1 + 1];
|
||||
strcpy(rsym, "_");
|
||||
strcat(rsym, sym.c_str());
|
||||
#else
|
||||
const char *rsym = sym.c_str();
|
||||
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.
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
#ifdef __WATCOMC__
|
||||
return *(DynamicLoader::SymbolPointer*)(&result);
|
||||
#else
|
||||
@@ -256,28 +242,22 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
//----------------------------------------------------------------------------
|
||||
const char* DynamicLoader::LastError()
|
||||
{
|
||||
LPVOID lpMsgBuf=NULL;
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
|
||||
if(!lpMsgBuf)
|
||||
{
|
||||
if (!lpMsgBuf) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static char* str = 0;
|
||||
delete [] str;
|
||||
str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
|
||||
delete[] str;
|
||||
str = strcpy(new char[strlen((char*)lpMsgBuf) + 1], (char*)lpMsgBuf);
|
||||
// Free the buffer.
|
||||
LocalFree( lpMsgBuf );
|
||||
LocalFree(lpMsgBuf);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -296,44 +276,39 @@ const char* DynamicLoader::LastError()
|
||||
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
static image_id last_dynamic_err = B_OK;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
// image_id's are integers, errors are negative. Add one just in case we
|
||||
// get a valid image_id of zero (is that even possible?).
|
||||
image_id rc = load_add_on(libname.c_str());
|
||||
if (rc < 0)
|
||||
{
|
||||
if (rc < 0) {
|
||||
last_dynamic_err = rc;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rc+1;
|
||||
return rc + 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
if (!lib)
|
||||
{
|
||||
last_dynamic_err = B_BAD_VALUE;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!lib) {
|
||||
last_dynamic_err = B_BAD_VALUE;
|
||||
return 0;
|
||||
} else {
|
||||
// The function dlclose() returns 0 on success, and non-zero on error.
|
||||
status_t rc = unload_add_on(lib-1);
|
||||
if (rc != B_OK)
|
||||
{
|
||||
status_t rc = unload_add_on(lib - 1);
|
||||
if (rc != B_OK) {
|
||||
last_dynamic_err = rc;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -343,7 +318,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
{
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
union
|
||||
union
|
||||
{
|
||||
void* pvoid;
|
||||
DynamicLoader::SymbolPointer psym;
|
||||
@@ -351,29 +326,26 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
|
||||
result.psym = NULL;
|
||||
|
||||
if (!lib)
|
||||
{
|
||||
last_dynamic_err = B_BAD_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!lib) {
|
||||
last_dynamic_err = B_BAD_VALUE;
|
||||
} else {
|
||||
// !!! FIXME: BeOS can do function-only lookups...does this ever
|
||||
// !!! FIXME: actually _want_ a data symbol lookup, or was this union
|
||||
// !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only).
|
||||
status_t rc = get_image_symbol(lib-1,sym.c_str(),B_SYMBOL_TYPE_ANY,&result.pvoid);
|
||||
if (rc != B_OK)
|
||||
{
|
||||
status_t rc =
|
||||
get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid);
|
||||
if (rc != B_OK) {
|
||||
last_dynamic_err = rc;
|
||||
result.psym = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.psym;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* DynamicLoader::LastError()
|
||||
{
|
||||
const char *retval = strerror(last_dynamic_err);
|
||||
const char* retval = strerror(last_dynamic_err);
|
||||
last_dynamic_err = B_OK;
|
||||
return retval;
|
||||
}
|
||||
@@ -385,15 +357,16 @@ const char* DynamicLoader::LastError()
|
||||
// 5. Implementation for systems without dynamic libs
|
||||
// __gnu_blrts__ is IBM BlueGene/L
|
||||
// __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes
|
||||
#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) || defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||
#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) || \
|
||||
defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
||||
#include <string.h> // for strerror()
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -401,26 +374,25 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libna
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
if (!lib)
|
||||
{
|
||||
if (!lib) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* DynamicLoader::LastError()
|
||||
{
|
||||
{
|
||||
return "General error";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
#endif
|
||||
@@ -428,28 +400,28 @@ const char* DynamicLoader::LastError()
|
||||
#ifdef __MINT__
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <dld.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
char *name = (char *)calloc(1, libname.size() + 1);
|
||||
char* name = (char*)calloc(1, libname.size() + 1);
|
||||
dld_init(program_invocation_name);
|
||||
strncpy(name, libname.c_str(), libname.size());
|
||||
dld_link(libname.c_str());
|
||||
return (void *)name;
|
||||
return (void*)name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
dld_unlink_by_file((char *)lib, 0);
|
||||
dld_unlink_by_file((char*)lib, 0);
|
||||
free(lib);
|
||||
return 0;
|
||||
}
|
||||
@@ -485,11 +457,11 @@ const char* DynamicLoader::LastError()
|
||||
// Setup for most unix machines
|
||||
#include <dlfcn.h>
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
|
||||
const std::string& libname)
|
||||
{
|
||||
return dlopen(libname.c_str(), RTLD_LAZY);
|
||||
}
|
||||
@@ -497,11 +469,10 @@ DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libna
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
if (lib)
|
||||
{
|
||||
if (lib) {
|
||||
// The function dlclose() returns 0 on success, and non-zero on error.
|
||||
return !dlclose(lib);
|
||||
}
|
||||
}
|
||||
// else
|
||||
return 0;
|
||||
}
|
||||
@@ -511,7 +482,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const std::string& sym)
|
||||
{
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
union
|
||||
union
|
||||
{
|
||||
void* pvoid;
|
||||
DynamicLoader::SymbolPointer psym;
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_DynamicLoader_hxx
|
||||
#define @KWSYS_NAMESPACE@_DynamicLoader_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <string>
|
||||
|
||||
#if defined(__hpux)
|
||||
#include <dl.h>
|
||||
#include <dl.h>
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <AvailabilityMacros.h>
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
#include <AvailabilityMacros.h>
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
#elif defined(__BEOS__)
|
||||
#include <be/kernel/image.h>
|
||||
#include <be/kernel/image.h>
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
/** \class DynamicLoader
|
||||
* \brief Portable loading of dynamic libraries or dll's.
|
||||
*
|
||||
@@ -61,14 +52,14 @@ public:
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__)
|
||||
typedef HMODULE LibraryHandle;
|
||||
#elif defined(__APPLE__)
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
|
||||
typedef NSModule LibraryHandle;
|
||||
#else
|
||||
typedef void* LibraryHandle;
|
||||
#endif
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
|
||||
typedef NSModule LibraryHandle;
|
||||
#else
|
||||
typedef void* LibraryHandle;
|
||||
#endif
|
||||
#elif defined(__BEOS__)
|
||||
typedef image_id LibraryHandle;
|
||||
#else // POSIX
|
||||
#else // POSIX
|
||||
typedef void* LibraryHandle;
|
||||
#endif
|
||||
|
||||
|
||||
+24
-34
@@ -1,18 +1,10 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Encoding_h
|
||||
#define @KWSYS_NAMESPACE@_Encoding_h
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.h>
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/* Redefine all public interface symbol names to be in the proper
|
||||
@@ -20,44 +12,42 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysEncoding kwsys_ns(Encoding)
|
||||
# define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs)
|
||||
# define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide)
|
||||
# define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs)
|
||||
# define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow)
|
||||
#define kwsysEncoding kwsys_ns(Encoding)
|
||||
#define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs)
|
||||
#define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide)
|
||||
#define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs)
|
||||
#define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a narrow string to a wide string.
|
||||
On Windows, UTF-8 is assumed, and on other platforms,
|
||||
the current locale is assumed.
|
||||
*/
|
||||
kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src, size_t n);
|
||||
kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src,
|
||||
size_t n);
|
||||
|
||||
/* Convert a narrow string to a wide string.
|
||||
This can return NULL if the conversion fails. */
|
||||
kwsysEXPORT wchar_t* kwsysEncoding_DupToWide(const char* src);
|
||||
|
||||
|
||||
/* Convert a wide string to a narrow string.
|
||||
On Windows, UTF-8 is assumed, and on other platforms,
|
||||
the current locale is assumed. */
|
||||
kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src, size_t n);
|
||||
kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src,
|
||||
size_t n);
|
||||
|
||||
/* Convert a wide string to a narrow string.
|
||||
This can return NULL if the conversion fails. */
|
||||
kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
@@ -65,15 +55,15 @@ kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str);
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysEncoding
|
||||
# undef kwsysEncoding_mbstowcs
|
||||
# undef kwsysEncoding_DupToWide
|
||||
# undef kwsysEncoding_wcstombs
|
||||
# undef kwsysEncoding_DupToNarrow
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysEncoding
|
||||
#undef kwsysEncoding_mbstowcs
|
||||
#undef kwsysEncoding_DupToWide
|
||||
#undef kwsysEncoding_wcstombs
|
||||
#undef kwsysEncoding_DupToNarrow
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,59 +1,49 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Encoding_hxx
|
||||
#define @KWSYS_NAMESPACE@_Encoding_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
class @KWSYS_NAMESPACE@_EXPORT Encoding
|
||||
{
|
||||
public:
|
||||
|
||||
// Container class for argc/argv.
|
||||
class CommandLineArguments
|
||||
{
|
||||
public:
|
||||
// On Windows, get the program command line arguments
|
||||
// in this Encoding module's 8 bit encoding.
|
||||
// On other platforms the given argc/argv is used, and
|
||||
// to be consistent, should be the argc/argv from main().
|
||||
static CommandLineArguments Main(int argc, char const* const* argv);
|
||||
public:
|
||||
// On Windows, get the program command line arguments
|
||||
// in this Encoding module's 8 bit encoding.
|
||||
// On other platforms the given argc/argv is used, and
|
||||
// to be consistent, should be the argc/argv from main().
|
||||
static CommandLineArguments Main(int argc, char const* const* argv);
|
||||
|
||||
// Construct CommandLineArguments with the given
|
||||
// argc/argv. It is assumed that the string is already
|
||||
// in the encoding used by this module.
|
||||
CommandLineArguments(int argc, char const* const* argv);
|
||||
// Construct CommandLineArguments with the given
|
||||
// argc/argv. It is assumed that the string is already
|
||||
// in the encoding used by this module.
|
||||
CommandLineArguments(int argc, char const* const* argv);
|
||||
|
||||
// Construct CommandLineArguments with the given
|
||||
// argc and wide argv. This is useful if wmain() is used.
|
||||
CommandLineArguments(int argc, wchar_t const* const* argv);
|
||||
~CommandLineArguments();
|
||||
CommandLineArguments(const CommandLineArguments&);
|
||||
CommandLineArguments& operator=(const CommandLineArguments&);
|
||||
// Construct CommandLineArguments with the given
|
||||
// argc and wide argv. This is useful if wmain() is used.
|
||||
CommandLineArguments(int argc, wchar_t const* const* argv);
|
||||
~CommandLineArguments();
|
||||
CommandLineArguments(const CommandLineArguments&);
|
||||
CommandLineArguments& operator=(const CommandLineArguments&);
|
||||
|
||||
int argc() const;
|
||||
char const* const* argv() const;
|
||||
int argc() const;
|
||||
char const* const* argv() const;
|
||||
|
||||
protected:
|
||||
std::vector<char*> argv_;
|
||||
protected:
|
||||
std::vector<char*> argv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert between char and wchar_t
|
||||
*/
|
||||
/**
|
||||
* Convert between char and wchar_t
|
||||
*/
|
||||
|
||||
#if @KWSYS_NAMESPACE@_STL_HAS_WSTRING
|
||||
|
||||
|
||||
+20
-33
@@ -1,21 +1,12 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Encoding.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Encoding.h.in"
|
||||
#include "Encoding.h.in"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -26,13 +17,13 @@
|
||||
|
||||
size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* str, size_t n)
|
||||
{
|
||||
if(str == 0)
|
||||
{
|
||||
if (str == 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0,
|
||||
str, -1, dest, (int)n) - 1;
|
||||
return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1, dest,
|
||||
(int)n) -
|
||||
1;
|
||||
#else
|
||||
return mbstowcs(dest, str, n);
|
||||
#endif
|
||||
@@ -42,27 +33,25 @@ wchar_t* kwsysEncoding_DupToWide(const char* str)
|
||||
{
|
||||
wchar_t* ret = NULL;
|
||||
size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1;
|
||||
if(length > 0)
|
||||
{
|
||||
ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
|
||||
if(ret)
|
||||
{
|
||||
if (length > 0) {
|
||||
ret = (wchar_t*)malloc((length) * sizeof(wchar_t));
|
||||
if (ret) {
|
||||
ret[0] = 0;
|
||||
kwsysEncoding_mbstowcs(ret, str, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* str, size_t n)
|
||||
{
|
||||
if(str == 0)
|
||||
{
|
||||
if (str == 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1,
|
||||
dest, (int)n, NULL, NULL) - 1;
|
||||
return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1, dest,
|
||||
(int)n, NULL, NULL) -
|
||||
1;
|
||||
#else
|
||||
return wcstombs(dest, str, n);
|
||||
#endif
|
||||
@@ -72,14 +61,12 @@ char* kwsysEncoding_DupToNarrow(const wchar_t* str)
|
||||
{
|
||||
char* ret = NULL;
|
||||
size_t length = kwsysEncoding_wcstombs(0, str, 0) + 1;
|
||||
if(length > 0)
|
||||
{
|
||||
if (length > 0) {
|
||||
ret = (char*)malloc(length);
|
||||
if(ret)
|
||||
{
|
||||
if (ret) {
|
||||
ret[0] = 0;
|
||||
kwsysEncoding_wcstombs(ret, str, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1,19 +1,9 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifdef __osf__
|
||||
# define _OSF_SOURCE
|
||||
# define _POSIX_C_SOURCE 199506L
|
||||
# define _XOPEN_SOURCE_EXTENDED
|
||||
#define _OSF_SOURCE
|
||||
#define _POSIX_C_SOURCE 199506L
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#endif
|
||||
|
||||
#include "kwsysPrivate.h"
|
||||
@@ -23,44 +13,43 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Encoding.hxx.in"
|
||||
# include "Encoding.h.in"
|
||||
#include "Encoding.h.in"
|
||||
#include "Encoding.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (disable: 4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
// Windows API.
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <shellapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
Encoding::CommandLineArguments
|
||||
Encoding::CommandLineArguments::Main(int argc, char const* const* argv)
|
||||
Encoding::CommandLineArguments Encoding::CommandLineArguments::Main(
|
||||
int argc, char const* const* argv)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
int ac;
|
||||
LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac);
|
||||
|
||||
std::vector<std::string> av1(ac);
|
||||
std::vector<char const*> av2(ac);
|
||||
for(int i=0; i<ac; i++)
|
||||
{
|
||||
for (int i = 0; i < ac; i++) {
|
||||
av1[i] = ToNarrow(w_av[i]);
|
||||
av2[i] = av1[i].c_str();
|
||||
}
|
||||
}
|
||||
LocalFree(w_av);
|
||||
return CommandLineArguments(ac, &av2[0]);
|
||||
#else
|
||||
@@ -71,60 +60,53 @@ Encoding::CommandLineArguments::Main(int argc, char const* const* argv)
|
||||
Encoding::CommandLineArguments::CommandLineArguments(int ac,
|
||||
char const* const* av)
|
||||
{
|
||||
this->argv_.resize(ac+1);
|
||||
for(int i=0; i<ac; i++)
|
||||
{
|
||||
this->argv_.resize(ac + 1);
|
||||
for (int i = 0; i < ac; i++) {
|
||||
this->argv_[i] = strdup(av[i]);
|
||||
}
|
||||
}
|
||||
this->argv_[ac] = 0;
|
||||
}
|
||||
|
||||
Encoding::CommandLineArguments::CommandLineArguments(int ac,
|
||||
wchar_t const* const* av)
|
||||
{
|
||||
this->argv_.resize(ac+1);
|
||||
for(int i=0; i<ac; i++)
|
||||
{
|
||||
this->argv_.resize(ac + 1);
|
||||
for (int i = 0; i < ac; i++) {
|
||||
this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
|
||||
}
|
||||
}
|
||||
this->argv_[ac] = 0;
|
||||
}
|
||||
|
||||
Encoding::CommandLineArguments::~CommandLineArguments()
|
||||
{
|
||||
for(size_t i=0; i<this->argv_.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < this->argv_.size(); i++) {
|
||||
free(argv_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Encoding::CommandLineArguments::
|
||||
CommandLineArguments(const CommandLineArguments& other)
|
||||
Encoding::CommandLineArguments::CommandLineArguments(
|
||||
const CommandLineArguments& other)
|
||||
{
|
||||
this->argv_.resize(other.argv_.size());
|
||||
for(size_t i=0; i<this->argv_.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < this->argv_.size(); i++) {
|
||||
this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Encoding::CommandLineArguments&
|
||||
Encoding::CommandLineArguments::operator=(const CommandLineArguments& other)
|
||||
Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=(
|
||||
const CommandLineArguments& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
size_t i;
|
||||
for(i=0; i<this->argv_.size(); i++)
|
||||
{
|
||||
for (i = 0; i < this->argv_.size(); i++) {
|
||||
free(this->argv_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this->argv_.resize(other.argv_.size());
|
||||
for(i=0; i<this->argv_.size(); i++)
|
||||
{
|
||||
for (i = 0; i < this->argv_.size(); i++) {
|
||||
this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -155,14 +137,12 @@ std::wstring Encoding::ToWide(const char* cstr)
|
||||
{
|
||||
std::wstring wstr;
|
||||
size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
|
||||
if(length > 0)
|
||||
{
|
||||
if (length > 0) {
|
||||
std::vector<wchar_t> wchars(length);
|
||||
if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0)
|
||||
{
|
||||
if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) {
|
||||
wstr = &wchars[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
|
||||
@@ -170,14 +150,12 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
|
||||
{
|
||||
std::string str;
|
||||
size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
|
||||
if(length > 0)
|
||||
{
|
||||
if (length > 0) {
|
||||
std::vector<char> chars(length);
|
||||
if(kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0)
|
||||
{
|
||||
if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) {
|
||||
str = &chars[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
#endif // KWSYS_STL_HAS_WSTRING
|
||||
|
||||
+22
-45
@@ -1,78 +1,55 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(FStream.hxx)
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "FStream.hxx.in"
|
||||
#include "FStream.hxx.in"
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace FStream
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
namespace FStream {
|
||||
|
||||
BOM ReadBOM(std::istream& in)
|
||||
{
|
||||
if(!in.good())
|
||||
{
|
||||
if (!in.good()) {
|
||||
return BOM_None;
|
||||
}
|
||||
}
|
||||
unsigned long orig = in.tellg();
|
||||
unsigned char bom[4];
|
||||
in.read(reinterpret_cast<char*>(bom), 2);
|
||||
if(!in.good())
|
||||
{
|
||||
if (!in.good()) {
|
||||
in.clear();
|
||||
in.seekg(orig);
|
||||
return BOM_None;
|
||||
}
|
||||
if(bom[0] == 0xEF && bom[1] == 0xBB)
|
||||
{
|
||||
in.read(reinterpret_cast<char*>(bom+2), 1);
|
||||
if(in.good() && bom[2] == 0xBF)
|
||||
{
|
||||
}
|
||||
if (bom[0] == 0xEF && bom[1] == 0xBB) {
|
||||
in.read(reinterpret_cast<char*>(bom + 2), 1);
|
||||
if (in.good() && bom[2] == 0xBF) {
|
||||
return BOM_UTF8;
|
||||
}
|
||||
}
|
||||
else if(bom[0] == 0xFE && bom[1] == 0xFF)
|
||||
{
|
||||
} else if (bom[0] == 0xFE && bom[1] == 0xFF) {
|
||||
return BOM_UTF16BE;
|
||||
}
|
||||
else if(bom[0] == 0x00 && bom[1] == 0x00)
|
||||
{
|
||||
in.read(reinterpret_cast<char*>(bom+2), 2);
|
||||
if(in.good() && bom[2] == 0xFE && bom[3] == 0xFF)
|
||||
{
|
||||
} else if (bom[0] == 0x00 && bom[1] == 0x00) {
|
||||
in.read(reinterpret_cast<char*>(bom + 2), 2);
|
||||
if (in.good() && bom[2] == 0xFE && bom[3] == 0xFF) {
|
||||
return BOM_UTF32BE;
|
||||
}
|
||||
}
|
||||
else if(bom[0] == 0xFF && bom[1] == 0xFE)
|
||||
{
|
||||
} else if (bom[0] == 0xFF && bom[1] == 0xFE) {
|
||||
unsigned long p = in.tellg();
|
||||
in.read(reinterpret_cast<char*>(bom+2), 2);
|
||||
if(in.good() && bom[2] == 0x00 && bom[3] == 0x00)
|
||||
{
|
||||
in.read(reinterpret_cast<char*>(bom + 2), 2);
|
||||
if (in.good() && bom[2] == 0x00 && bom[3] == 0x00) {
|
||||
return BOM_UTF32LE;
|
||||
}
|
||||
}
|
||||
in.seekg(p);
|
||||
return BOM_UTF16LE;
|
||||
}
|
||||
}
|
||||
in.clear();
|
||||
in.seekg(orig);
|
||||
return BOM_None;
|
||||
}
|
||||
|
||||
} // FStream namespace
|
||||
} //KWSYS_NAMESPACE
|
||||
} // KWSYS_NAMESPACE
|
||||
+242
-254
@@ -1,288 +1,276 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_FStream_hxx
|
||||
#define @KWSYS_NAMESPACE@_FStream_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Encoding.hxx>
|
||||
|
||||
#include <fstream>
|
||||
#if defined(_WIN32)
|
||||
# if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
|
||||
# include <ext/stdio_filebuf.h>
|
||||
# endif
|
||||
#if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
|
||||
#include <ext/stdio_filebuf.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
#if defined(_WIN32) && \
|
||||
(defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
|
||||
#if defined(_NOEXCEPT)
|
||||
#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
|
||||
#else
|
||||
#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
template <typename CharType, typename Traits>
|
||||
class basic_filebuf : public std::basic_filebuf<CharType, Traits>
|
||||
{
|
||||
#if defined(_WIN32) && (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
|
||||
# if defined(_NOEXCEPT)
|
||||
# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
|
||||
# else
|
||||
# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
# endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
template<typename CharType,typename Traits>
|
||||
class basic_filebuf : public std::basic_filebuf<CharType,Traits>
|
||||
#if _MSC_VER >= 1400
|
||||
public:
|
||||
typedef std::basic_filebuf<CharType, Traits> my_base_type;
|
||||
basic_filebuf* open(char const* s, std::ios_base::openmode mode)
|
||||
{
|
||||
# if _MSC_VER >= 1400
|
||||
public:
|
||||
typedef std::basic_filebuf<CharType,Traits> my_base_type;
|
||||
basic_filebuf *open(char const *s,std::ios_base::openmode mode)
|
||||
{
|
||||
const std::wstring wstr = Encoding::ToWide(s);
|
||||
return static_cast<basic_filebuf*>(
|
||||
my_base_type::open(wstr.c_str(), mode)
|
||||
);
|
||||
}
|
||||
# endif
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
inline std::wstring getcmode(const std::ios_base::openmode mode) {
|
||||
std::wstring cmode;
|
||||
bool plus = false;
|
||||
if (mode & std::ios_base::app) {
|
||||
cmode += L"a";
|
||||
plus = mode & std::ios_base::in ? true : false;
|
||||
} else if (mode & std::ios_base::trunc ||
|
||||
(mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
|
||||
cmode += L"w";
|
||||
plus = mode & std::ios_base::in ? true : false;
|
||||
} else {
|
||||
cmode += L"r";
|
||||
plus = mode & std::ios_base::out ? true : false;
|
||||
}
|
||||
if (plus) {
|
||||
cmode += L"+";
|
||||
}
|
||||
if (mode & std::ios_base::binary) {
|
||||
cmode += L"b";
|
||||
} else {
|
||||
cmode += L"t";
|
||||
}
|
||||
return cmode;
|
||||
};
|
||||
|
||||
const std::wstring wstr = Encoding::ToWide(s);
|
||||
return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
class basic_efilebuf
|
||||
{
|
||||
public:
|
||||
#if defined(_MSC_VER)
|
||||
typedef basic_filebuf<CharType,Traits> internal_buffer_type;
|
||||
#else
|
||||
typedef __gnu_cxx::stdio_filebuf<CharType,Traits> internal_buffer_type;
|
||||
#endif
|
||||
|
||||
basic_efilebuf() : file_(0)
|
||||
{
|
||||
buf_ = 0;
|
||||
}
|
||||
|
||||
bool _open(char const *file_name,std::ios_base::openmode mode)
|
||||
{
|
||||
if (is_open() || file_) {
|
||||
return false;
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
const bool success = buf_->open(file_name,mode) != 0;
|
||||
#else
|
||||
const std::wstring wstr = Encoding::ToWide(file_name);
|
||||
bool success = false;
|
||||
std::wstring cmode = getcmode(mode);
|
||||
file_ = _wfopen(wstr.c_str(), cmode.c_str());
|
||||
if (file_) {
|
||||
if (buf_) {
|
||||
delete buf_;
|
||||
}
|
||||
buf_ = new internal_buffer_type(file_, mode);
|
||||
success = true;
|
||||
}
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
bool is_open()
|
||||
{
|
||||
if (!buf_) {
|
||||
return false;
|
||||
}
|
||||
return buf_->is_open();
|
||||
}
|
||||
|
||||
bool is_open() const
|
||||
{
|
||||
if (!buf_) {
|
||||
return false;
|
||||
}
|
||||
return buf_->is_open();
|
||||
}
|
||||
|
||||
bool _close()
|
||||
{
|
||||
bool success = false;
|
||||
if (buf_) {
|
||||
success = buf_->close() != 0;
|
||||
#if !defined(_MSC_VER)
|
||||
if (file_) {
|
||||
success = fclose(file_) == 0 ? success : false;
|
||||
file_ = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static void _set_state(bool success, std::basic_ios<CharType,Traits> *ios, basic_efilebuf* efilebuf)
|
||||
{
|
||||
#if !defined(_MSC_VER)
|
||||
ios->rdbuf(efilebuf->buf_);
|
||||
#endif
|
||||
if (!success) {
|
||||
ios->setstate(std::ios_base::failbit);
|
||||
} else {
|
||||
ios->clear();
|
||||
}
|
||||
}
|
||||
|
||||
~basic_efilebuf()
|
||||
{
|
||||
if (buf_) {
|
||||
delete buf_;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
internal_buffer_type* buf_;
|
||||
FILE *file_;
|
||||
};
|
||||
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
class basic_ifstream : public std::basic_istream<CharType,Traits>,
|
||||
public basic_efilebuf<CharType,Traits>
|
||||
{
|
||||
using basic_efilebuf<CharType,Traits>::is_open;
|
||||
|
||||
public:
|
||||
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
|
||||
typedef std::basic_istream<CharType,Traits> internal_stream_type;
|
||||
|
||||
basic_ifstream() : internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
|
||||
}
|
||||
explicit basic_ifstream(char const *file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in)
|
||||
: internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
|
||||
open(file_name,mode);
|
||||
}
|
||||
|
||||
void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
mode = mode | std::ios_base::in;
|
||||
this->_set_state(this->_open(file_name, mode), this, this);
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
this->_set_state(this->_close(), this, this);
|
||||
}
|
||||
|
||||
internal_buffer_type *rdbuf() const
|
||||
{
|
||||
return this->buf_;
|
||||
}
|
||||
|
||||
~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
{
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
class basic_ofstream : public std::basic_ostream<CharType,Traits>,
|
||||
public basic_efilebuf<CharType,Traits>
|
||||
#else
|
||||
|
||||
inline std::wstring getcmode(const std::ios_base::openmode mode)
|
||||
{
|
||||
using basic_efilebuf<CharType,Traits>::is_open;
|
||||
|
||||
public:
|
||||
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
|
||||
typedef std::basic_ostream<CharType,Traits> internal_stream_type;
|
||||
|
||||
basic_ofstream() : internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
|
||||
std::wstring cmode;
|
||||
bool plus = false;
|
||||
if (mode & std::ios_base::app) {
|
||||
cmode += L"a";
|
||||
plus = mode & std::ios_base::in ? true : false;
|
||||
} else if (mode & std::ios_base::trunc ||
|
||||
(mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
|
||||
cmode += L"w";
|
||||
plus = mode & std::ios_base::in ? true : false;
|
||||
} else {
|
||||
cmode += L"r";
|
||||
plus = mode & std::ios_base::out ? true : false;
|
||||
}
|
||||
explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
|
||||
internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
|
||||
open(file_name,mode);
|
||||
if (plus) {
|
||||
cmode += L"+";
|
||||
}
|
||||
void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
|
||||
if (mode & std::ios_base::binary) {
|
||||
cmode += L"b";
|
||||
} else {
|
||||
cmode += L"t";
|
||||
}
|
||||
return cmode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename CharType, typename Traits = std::char_traits<CharType> >
|
||||
class basic_efilebuf
|
||||
{
|
||||
public:
|
||||
#if defined(_MSC_VER)
|
||||
typedef basic_filebuf<CharType, Traits> internal_buffer_type;
|
||||
#else
|
||||
typedef __gnu_cxx::stdio_filebuf<CharType, Traits> internal_buffer_type;
|
||||
#endif
|
||||
|
||||
basic_efilebuf()
|
||||
: file_(0)
|
||||
{
|
||||
buf_ = 0;
|
||||
}
|
||||
|
||||
bool _open(char const* file_name, std::ios_base::openmode mode)
|
||||
{
|
||||
if (is_open() || file_) {
|
||||
return false;
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
const bool success = buf_->open(file_name, mode) != 0;
|
||||
#else
|
||||
const std::wstring wstr = Encoding::ToWide(file_name);
|
||||
bool success = false;
|
||||
std::wstring cmode = getcmode(mode);
|
||||
file_ = _wfopen(wstr.c_str(), cmode.c_str());
|
||||
if (file_) {
|
||||
if (buf_) {
|
||||
delete buf_;
|
||||
}
|
||||
buf_ = new internal_buffer_type(file_, mode);
|
||||
success = true;
|
||||
}
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
bool is_open()
|
||||
{
|
||||
if (!buf_) {
|
||||
return false;
|
||||
}
|
||||
return buf_->is_open();
|
||||
}
|
||||
|
||||
bool is_open() const
|
||||
{
|
||||
if (!buf_) {
|
||||
return false;
|
||||
}
|
||||
return buf_->is_open();
|
||||
}
|
||||
|
||||
bool _close()
|
||||
{
|
||||
bool success = false;
|
||||
if (buf_) {
|
||||
success = buf_->close() != 0;
|
||||
#if !defined(_MSC_VER)
|
||||
if (file_) {
|
||||
success = fclose(file_) == 0 ? success : false;
|
||||
file_ = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static void _set_state(bool success, std::basic_ios<CharType, Traits>* ios,
|
||||
basic_efilebuf* efilebuf)
|
||||
{
|
||||
#if !defined(_MSC_VER)
|
||||
ios->rdbuf(efilebuf->buf_);
|
||||
#else
|
||||
static_cast<void>(efilebuf);
|
||||
#endif
|
||||
if (!success) {
|
||||
ios->setstate(std::ios_base::failbit);
|
||||
} else {
|
||||
ios->clear();
|
||||
}
|
||||
}
|
||||
|
||||
~basic_efilebuf()
|
||||
{
|
||||
if (buf_) {
|
||||
delete buf_;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
internal_buffer_type* buf_;
|
||||
FILE* file_;
|
||||
};
|
||||
|
||||
template <typename CharType, typename Traits = std::char_traits<CharType> >
|
||||
class basic_ifstream : public std::basic_istream<CharType, Traits>,
|
||||
public basic_efilebuf<CharType, Traits>
|
||||
{
|
||||
using basic_efilebuf<CharType, Traits>::is_open;
|
||||
|
||||
public:
|
||||
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
|
||||
internal_buffer_type;
|
||||
typedef std::basic_istream<CharType, Traits> internal_stream_type;
|
||||
|
||||
basic_ifstream()
|
||||
: internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ =
|
||||
static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
|
||||
}
|
||||
explicit basic_ifstream(char const* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in)
|
||||
: internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ =
|
||||
static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
|
||||
open(file_name, mode);
|
||||
}
|
||||
|
||||
void open(char const* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
mode = mode | std::ios_base::in;
|
||||
this->_set_state(this->_open(file_name, mode), this, this);
|
||||
}
|
||||
|
||||
void close() { this->_set_state(this->_close(), this, this); }
|
||||
|
||||
internal_buffer_type* rdbuf() const { return this->buf_; }
|
||||
|
||||
~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
|
||||
};
|
||||
|
||||
template <typename CharType, typename Traits = std::char_traits<CharType> >
|
||||
class basic_ofstream : public std::basic_ostream<CharType, Traits>,
|
||||
public basic_efilebuf<CharType, Traits>
|
||||
{
|
||||
using basic_efilebuf<CharType, Traits>::is_open;
|
||||
|
||||
public:
|
||||
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
|
||||
internal_buffer_type;
|
||||
typedef std::basic_ostream<CharType, Traits> internal_stream_type;
|
||||
|
||||
basic_ofstream()
|
||||
: internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ =
|
||||
static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
|
||||
}
|
||||
explicit basic_ofstream(char const* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::out)
|
||||
: internal_stream_type(new internal_buffer_type())
|
||||
{
|
||||
this->buf_ =
|
||||
static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
|
||||
open(file_name, mode);
|
||||
}
|
||||
void open(char const* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::out)
|
||||
{
|
||||
mode = mode | std::ios_base::out;
|
||||
this->_set_state(this->_open(file_name, mode), this, this);
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
this->_set_state(this->_close(), this, this);
|
||||
}
|
||||
void close() { this->_set_state(this->_close(), this, this); }
|
||||
|
||||
internal_buffer_type *rdbuf() const
|
||||
{
|
||||
return this->buf_;
|
||||
}
|
||||
internal_buffer_type* rdbuf() const { return this->buf_; }
|
||||
|
||||
~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
{
|
||||
close();
|
||||
}
|
||||
~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
|
||||
};
|
||||
|
||||
typedef basic_ifstream<char> ifstream;
|
||||
typedef basic_ofstream<char> ofstream;
|
||||
typedef basic_ifstream<char> ifstream;
|
||||
typedef basic_ofstream<char> ofstream;
|
||||
|
||||
# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
#undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
|
||||
#else
|
||||
using std::ofstream;
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::ifstream;
|
||||
#endif
|
||||
|
||||
namespace FStream
|
||||
{
|
||||
enum BOM
|
||||
{
|
||||
BOM_None,
|
||||
BOM_UTF8,
|
||||
BOM_UTF16BE,
|
||||
BOM_UTF16LE,
|
||||
BOM_UTF32BE,
|
||||
BOM_UTF32LE
|
||||
};
|
||||
namespace FStream {
|
||||
enum BOM
|
||||
{
|
||||
BOM_None,
|
||||
BOM_UTF8,
|
||||
BOM_UTF16BE,
|
||||
BOM_UTF16LE,
|
||||
BOM_UTF32BE,
|
||||
BOM_UTF32LE
|
||||
};
|
||||
|
||||
// Read a BOM, if one exists.
|
||||
// If a BOM exists, the stream is advanced to after the BOM.
|
||||
// This function requires a seekable stream (but not a relative
|
||||
// seekable stream).
|
||||
BOM ReadBOM(std::istream& in);
|
||||
}
|
||||
// Read a BOM, if one exists.
|
||||
// If a BOM exists, the stream is advanced to after the BOM.
|
||||
// This function requires a seekable stream (but not a relative
|
||||
// seekable stream).
|
||||
BOM ReadBOM(std::istream& in);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+159
-259
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Glob.hxx)
|
||||
|
||||
@@ -21,30 +12,29 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Glob.hxx.in"
|
||||
# include "Directory.hxx.in"
|
||||
# include "Configure.hxx.in"
|
||||
# include "RegularExpression.hxx.in"
|
||||
# include "SystemTools.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#include "Directory.hxx.in"
|
||||
#include "Glob.hxx.in"
|
||||
#include "RegularExpression.hxx.in"
|
||||
#include "SystemTools.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
|
||||
// On Windows and apple, no difference between lower and upper case
|
||||
# define KWSYS_GLOB_CASE_INDEPENDENT
|
||||
#define KWSYS_GLOB_CASE_INDEPENDENT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
// Handle network paths
|
||||
# define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
|
||||
#define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -63,8 +53,8 @@ Glob::Glob()
|
||||
this->Relative = "";
|
||||
|
||||
this->RecurseThroughSymlinks = true;
|
||||
// RecurseThroughSymlinks is true by default for backwards compatibility,
|
||||
// not because it's a good idea...
|
||||
// RecurseThroughSymlinks is true by default for backwards compatibility,
|
||||
// not because it's a good idea...
|
||||
this->FollowedSymlinkCount = 0;
|
||||
|
||||
// Keep separate variables for directory listing for back compatibility
|
||||
@@ -86,69 +76,55 @@ std::vector<std::string>& Glob::GetFiles()
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string Glob::PatternToRegex(const std::string& pattern,
|
||||
bool require_whole_string,
|
||||
bool preserve_case)
|
||||
bool require_whole_string, bool preserve_case)
|
||||
{
|
||||
// Incrementally build the regular expression from the pattern.
|
||||
std::string regex = require_whole_string? "^" : "";
|
||||
std::string regex = require_whole_string ? "^" : "";
|
||||
std::string::const_iterator pattern_first = pattern.begin();
|
||||
std::string::const_iterator pattern_last = pattern.end();
|
||||
for(std::string::const_iterator i = pattern_first;
|
||||
i != pattern_last; ++i)
|
||||
{
|
||||
for (std::string::const_iterator i = pattern_first; i != pattern_last; ++i) {
|
||||
int c = *i;
|
||||
if(c == '*')
|
||||
{
|
||||
if (c == '*') {
|
||||
// A '*' (not between brackets) matches any string.
|
||||
// We modify this to not match slashes since the orignal glob
|
||||
// pattern documentation was meant for matching file name
|
||||
// components separated by slashes.
|
||||
regex += "[^/]*";
|
||||
}
|
||||
else if(c == '?')
|
||||
{
|
||||
} else if (c == '?') {
|
||||
// A '?' (not between brackets) matches any single character.
|
||||
// We modify this to not match slashes since the orignal glob
|
||||
// pattern documentation was meant for matching file name
|
||||
// components separated by slashes.
|
||||
regex += "[^/]";
|
||||
}
|
||||
else if(c == '[')
|
||||
{
|
||||
} else if (c == '[') {
|
||||
// Parse out the bracket expression. It begins just after the
|
||||
// opening character.
|
||||
std::string::const_iterator bracket_first = i+1;
|
||||
std::string::const_iterator bracket_first = i + 1;
|
||||
std::string::const_iterator bracket_last = bracket_first;
|
||||
|
||||
// The first character may be complementation '!' or '^'.
|
||||
if(bracket_last != pattern_last &&
|
||||
(*bracket_last == '!' || *bracket_last == '^'))
|
||||
{
|
||||
if (bracket_last != pattern_last &&
|
||||
(*bracket_last == '!' || *bracket_last == '^')) {
|
||||
++bracket_last;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next character is a ']' it is included in the brackets
|
||||
// because the bracket string may not be empty.
|
||||
if(bracket_last != pattern_last && *bracket_last == ']')
|
||||
{
|
||||
if (bracket_last != pattern_last && *bracket_last == ']') {
|
||||
++bracket_last;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for the closing ']'.
|
||||
while(bracket_last != pattern_last && *bracket_last != ']')
|
||||
{
|
||||
while (bracket_last != pattern_last && *bracket_last != ']') {
|
||||
++bracket_last;
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we have a complete bracket string.
|
||||
if(bracket_last == pattern_last)
|
||||
{
|
||||
if (bracket_last == pattern_last) {
|
||||
// The bracket string did not end, so it was opened simply by
|
||||
// a '[' that is supposed to be matched literally.
|
||||
regex += "\\[";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Convert the bracket string to its regex equivalent.
|
||||
std::string::const_iterator k = bracket_first;
|
||||
|
||||
@@ -156,97 +132,81 @@ std::string Glob::PatternToRegex(const std::string& pattern,
|
||||
regex += "[";
|
||||
|
||||
// A regex range complement uses '^' instead of '!'.
|
||||
if(k != bracket_last && *k == '!')
|
||||
{
|
||||
if (k != bracket_last && *k == '!') {
|
||||
regex += "^";
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the remaining characters.
|
||||
for(; k != bracket_last; ++k)
|
||||
{
|
||||
for (; k != bracket_last; ++k) {
|
||||
// Backslashes must be escaped.
|
||||
if(*k == '\\')
|
||||
{
|
||||
if (*k == '\\') {
|
||||
regex += "\\";
|
||||
}
|
||||
}
|
||||
|
||||
// Store this character.
|
||||
regex += *k;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the regex block.
|
||||
regex += "]";
|
||||
|
||||
// Jump to the end of the bracket string.
|
||||
i = bracket_last;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// A single character matches itself.
|
||||
int ch = c;
|
||||
if(!(('a' <= ch && ch <= 'z') ||
|
||||
('A' <= ch && ch <= 'Z') ||
|
||||
('0' <= ch && ch <= '9')))
|
||||
{
|
||||
if (!(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
|
||||
('0' <= ch && ch <= '9'))) {
|
||||
// Escape the non-alphanumeric character.
|
||||
regex += "\\";
|
||||
}
|
||||
}
|
||||
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
|
||||
else
|
||||
{
|
||||
else {
|
||||
// On case-insensitive systems file names are converted to lower
|
||||
// case before matching.
|
||||
if(!preserve_case)
|
||||
{
|
||||
if (!preserve_case) {
|
||||
ch = tolower(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void)preserve_case;
|
||||
// Store the character.
|
||||
regex.append(1, static_cast<char>(ch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(require_whole_string)
|
||||
{
|
||||
if (require_whole_string) {
|
||||
regex += "$";
|
||||
}
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool Glob::RecurseDirectory(std::string::size_type start,
|
||||
const std::string& dir, GlobMessages* messages)
|
||||
const std::string& dir, GlobMessages* messages)
|
||||
{
|
||||
kwsys::Directory d;
|
||||
if ( !d.Load(dir) )
|
||||
{
|
||||
if (!d.Load(dir)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unsigned long cc;
|
||||
std::string realname;
|
||||
std::string fname;
|
||||
for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
|
||||
{
|
||||
for (cc = 0; cc < d.GetNumberOfFiles(); cc++) {
|
||||
fname = d.GetFile(cc);
|
||||
if ( fname == "." || fname == ".." )
|
||||
{
|
||||
if (fname == "." || fname == "..") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( start == 0 )
|
||||
{
|
||||
if (start == 0) {
|
||||
realname = dir + fname;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
realname = dir + "/" + fname;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( KWSYS_GLOB_CASE_INDEPENDENT )
|
||||
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
|
||||
// On Windows and apple, no difference between lower and upper case
|
||||
fname = kwsys::SystemTools::LowerCase(fname);
|
||||
#endif
|
||||
@@ -254,157 +214,127 @@ bool Glob::RecurseDirectory(std::string::size_type start,
|
||||
bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
|
||||
bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);
|
||||
|
||||
if ( isDir && (!isSymLink || this->RecurseThroughSymlinks) )
|
||||
{
|
||||
if (isSymLink)
|
||||
{
|
||||
if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) {
|
||||
if (isSymLink) {
|
||||
++this->FollowedSymlinkCount;
|
||||
std::string realPathErrorMessage;
|
||||
std::string canonicalPath(SystemTools::GetRealPath(dir,
|
||||
&realPathErrorMessage));
|
||||
std::string canonicalPath(
|
||||
SystemTools::GetRealPath(dir, &realPathErrorMessage));
|
||||
|
||||
if(!realPathErrorMessage.empty())
|
||||
{
|
||||
if(messages)
|
||||
{
|
||||
if (!realPathErrorMessage.empty()) {
|
||||
if (messages) {
|
||||
messages->push_back(Message(
|
||||
Glob::error, "Canonical path generation from path '"
|
||||
+ dir + "' failed! Reason: '" + realPathErrorMessage + "'"));
|
||||
}
|
||||
return false;
|
||||
Glob::error, "Canonical path generation from path '" + dir +
|
||||
"' failed! Reason: '" + realPathErrorMessage + "'"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(std::find(this->VisitedSymlinks.begin(),
|
||||
this->VisitedSymlinks.end(),
|
||||
canonicalPath) == this->VisitedSymlinks.end())
|
||||
{
|
||||
if(this->RecurseListDirs)
|
||||
{
|
||||
if (std::find(this->VisitedSymlinks.begin(),
|
||||
this->VisitedSymlinks.end(),
|
||||
canonicalPath) == this->VisitedSymlinks.end()) {
|
||||
if (this->RecurseListDirs) {
|
||||
// symlinks are treated as directories
|
||||
this->AddFile(this->Internals->Files, realname);
|
||||
}
|
||||
}
|
||||
|
||||
this->VisitedSymlinks.push_back(canonicalPath);
|
||||
if(!this->RecurseDirectory(start+1, realname, messages))
|
||||
{
|
||||
if (!this->RecurseDirectory(start + 1, realname, messages)) {
|
||||
this->VisitedSymlinks.pop_back();
|
||||
|
||||
return false;
|
||||
}
|
||||
this->VisitedSymlinks.pop_back();
|
||||
}
|
||||
this->VisitedSymlinks.pop_back();
|
||||
}
|
||||
// else we have already visited this symlink - prevent cyclic recursion
|
||||
else if(messages)
|
||||
{
|
||||
else if (messages) {
|
||||
std::string message;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
pathIt = std::find(this->VisitedSymlinks.begin(),
|
||||
this->VisitedSymlinks.end(),
|
||||
canonicalPath);
|
||||
pathIt != this->VisitedSymlinks.end(); ++pathIt)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator pathIt =
|
||||
std::find(this->VisitedSymlinks.begin(),
|
||||
this->VisitedSymlinks.end(), canonicalPath);
|
||||
pathIt != this->VisitedSymlinks.end(); ++pathIt) {
|
||||
message += *pathIt + "\n";
|
||||
}
|
||||
}
|
||||
message += canonicalPath + "/" + fname;
|
||||
messages->push_back(Message(Glob::cyclicRecursion, message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this->RecurseListDirs)
|
||||
{
|
||||
} else {
|
||||
if (this->RecurseListDirs) {
|
||||
this->AddFile(this->Internals->Files, realname);
|
||||
}
|
||||
if(!this->RecurseDirectory(start+1, realname, messages))
|
||||
{
|
||||
}
|
||||
if (!this->RecurseDirectory(start + 1, realname, messages)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !this->Internals->Expressions.empty() &&
|
||||
this->Internals->Expressions.rbegin()->find(fname) )
|
||||
{
|
||||
} else {
|
||||
if (!this->Internals->Expressions.empty() &&
|
||||
this->Internals->Expressions.rbegin()->find(fname)) {
|
||||
this->AddFile(this->Internals->Files, realname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Glob::ProcessDirectory(std::string::size_type start,
|
||||
const std::string& dir, GlobMessages* messages)
|
||||
const std::string& dir, GlobMessages* messages)
|
||||
{
|
||||
//std::cout << "ProcessDirectory: " << dir << std::endl;
|
||||
bool last = ( start == this->Internals->Expressions.size()-1 );
|
||||
if ( last && this->Recurse )
|
||||
{
|
||||
// std::cout << "ProcessDirectory: " << dir << std::endl;
|
||||
bool last = (start == this->Internals->Expressions.size() - 1);
|
||||
if (last && this->Recurse) {
|
||||
this->RecurseDirectory(start, dir, messages);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( start >= this->Internals->Expressions.size() )
|
||||
{
|
||||
if (start >= this->Internals->Expressions.size()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
kwsys::Directory d;
|
||||
if ( !d.Load(dir) )
|
||||
{
|
||||
if (!d.Load(dir)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
unsigned long cc;
|
||||
std::string realname;
|
||||
std::string fname;
|
||||
for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
|
||||
{
|
||||
for (cc = 0; cc < d.GetNumberOfFiles(); cc++) {
|
||||
fname = d.GetFile(cc);
|
||||
if ( fname == "." || fname == ".." )
|
||||
{
|
||||
if (fname == "." || fname == "..") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( start == 0 )
|
||||
{
|
||||
if (start == 0) {
|
||||
realname = dir + fname;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
realname = dir + "/" + fname;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
|
||||
// On case-insensitive file systems convert to lower case for matching.
|
||||
fname = kwsys::SystemTools::LowerCase(fname);
|
||||
#endif
|
||||
|
||||
//std::cout << "Look at file: " << fname << std::endl;
|
||||
//std::cout << "Match: "
|
||||
// std::cout << "Look at file: " << fname << std::endl;
|
||||
// std::cout << "Match: "
|
||||
// << this->Internals->TextExpressions[start].c_str() << std::endl;
|
||||
//std::cout << "Real name: " << realname << std::endl;
|
||||
// std::cout << "Real name: " << realname << std::endl;
|
||||
|
||||
if( (!last && !kwsys::SystemTools::FileIsDirectory(realname))
|
||||
|| (!this->ListDirs && last &&
|
||||
kwsys::SystemTools::FileIsDirectory(realname)) )
|
||||
{
|
||||
if ((!last && !kwsys::SystemTools::FileIsDirectory(realname)) ||
|
||||
(!this->ListDirs && last &&
|
||||
kwsys::SystemTools::FileIsDirectory(realname))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( this->Internals->Expressions[start].find(fname) )
|
||||
{
|
||||
if ( last )
|
||||
{
|
||||
if (this->Internals->Expressions[start].find(fname)) {
|
||||
if (last) {
|
||||
this->AddFile(this->Internals->Files, realname);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ProcessDirectory(start+1, realname, messages);
|
||||
}
|
||||
} else {
|
||||
this->ProcessDirectory(start + 1, realname, messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -417,99 +347,76 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
|
||||
this->Internals->Expressions.clear();
|
||||
this->Internals->Files.clear();
|
||||
|
||||
if ( !kwsys::SystemTools::FileIsFullPath(expr) )
|
||||
{
|
||||
if (!kwsys::SystemTools::FileIsFullPath(expr)) {
|
||||
expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
|
||||
expr += "/" + inexpr;
|
||||
}
|
||||
}
|
||||
std::string fexpr = expr;
|
||||
|
||||
std::string::size_type skip = 0;
|
||||
std::string::size_type last_slash = 0;
|
||||
for ( cc = 0; cc < expr.size(); cc ++ )
|
||||
{
|
||||
if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
|
||||
{
|
||||
for (cc = 0; cc < expr.size(); cc++) {
|
||||
if (cc > 0 && expr[cc] == '/' && expr[cc - 1] != '\\') {
|
||||
last_slash = cc;
|
||||
}
|
||||
if ( cc > 0 &&
|
||||
(expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
|
||||
expr[cc-1] != '\\' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( last_slash > 0 )
|
||||
{
|
||||
//std::cout << "I can skip: " << fexpr.substr(0, last_slash)
|
||||
if (cc > 0 && (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
|
||||
expr[cc - 1] != '\\') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (last_slash > 0) {
|
||||
// std::cout << "I can skip: " << fexpr.substr(0, last_slash)
|
||||
// << std::endl;
|
||||
skip = last_slash;
|
||||
}
|
||||
if ( skip == 0 )
|
||||
{
|
||||
#if defined( KWSYS_GLOB_SUPPORT_NETWORK_PATHS )
|
||||
}
|
||||
if (skip == 0) {
|
||||
#if defined(KWSYS_GLOB_SUPPORT_NETWORK_PATHS)
|
||||
// Handle network paths
|
||||
if ( expr[0] == '/' && expr[1] == '/' )
|
||||
{
|
||||
if (expr[0] == '/' && expr[1] == '/') {
|
||||
int cnt = 0;
|
||||
for ( cc = 2; cc < expr.size(); cc ++ )
|
||||
{
|
||||
if ( expr[cc] == '/' )
|
||||
{
|
||||
cnt ++;
|
||||
if ( cnt == 2 )
|
||||
{
|
||||
for (cc = 2; cc < expr.size(); cc++) {
|
||||
if (expr[cc] == '/') {
|
||||
cnt++;
|
||||
if (cnt == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
skip = int(cc + 1);
|
||||
}
|
||||
else
|
||||
skip = int(cc + 1);
|
||||
} else
|
||||
#endif
|
||||
// Handle drive letters on Windows
|
||||
if ( expr[1] == ':' && expr[0] != '/' )
|
||||
{
|
||||
skip = 2;
|
||||
}
|
||||
if (expr[1] == ':' && expr[0] != '/') {
|
||||
skip = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( skip > 0 )
|
||||
{
|
||||
if (skip > 0) {
|
||||
expr = expr.substr(skip);
|
||||
}
|
||||
}
|
||||
|
||||
cexpr = "";
|
||||
for ( cc = 0; cc < expr.size(); cc ++ )
|
||||
{
|
||||
for (cc = 0; cc < expr.size(); cc++) {
|
||||
int ch = expr[cc];
|
||||
if ( ch == '/' )
|
||||
{
|
||||
if ( !cexpr.empty() )
|
||||
{
|
||||
if (ch == '/') {
|
||||
if (!cexpr.empty()) {
|
||||
this->AddExpression(cexpr);
|
||||
}
|
||||
}
|
||||
cexpr = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cexpr.append(1, static_cast<char>(ch));
|
||||
}
|
||||
}
|
||||
if ( !cexpr.empty() )
|
||||
{
|
||||
}
|
||||
if (!cexpr.empty()) {
|
||||
this->AddExpression(cexpr);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle network paths
|
||||
if ( skip > 0 )
|
||||
{
|
||||
if (skip > 0) {
|
||||
this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this->ProcessDirectory(0, "/", messages);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -517,43 +424,36 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
|
||||
void Glob::AddExpression(const std::string& expr)
|
||||
{
|
||||
this->Internals->Expressions.push_back(
|
||||
kwsys::RegularExpression(
|
||||
this->PatternToRegex(expr)));
|
||||
kwsys::RegularExpression(this->PatternToRegex(expr)));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Glob::SetRelative(const char* dir)
|
||||
{
|
||||
if ( !dir )
|
||||
{
|
||||
if (!dir) {
|
||||
this->Relative = "";
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->Relative = dir;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* Glob::GetRelative()
|
||||
{
|
||||
if ( this->Relative.empty() )
|
||||
{
|
||||
if (this->Relative.empty()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return this->Relative.c_str();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Glob::AddFile(std::vector<std::string>& files, const std::string& file)
|
||||
{
|
||||
if ( !this->Relative.empty() )
|
||||
{
|
||||
if (!this->Relative.empty()) {
|
||||
files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
files.push_back(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
|
||||
+27
-37
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Glob_hxx
|
||||
#define @KWSYS_NAMESPACE@_Glob_hxx
|
||||
|
||||
@@ -18,8 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
class GlobInternals;
|
||||
|
||||
@@ -46,31 +36,33 @@ public:
|
||||
MessageType type;
|
||||
std::string content;
|
||||
|
||||
Message(MessageType t, const std::string& c) :
|
||||
type(t),
|
||||
content(c)
|
||||
{}
|
||||
Message(const Message& msg) :
|
||||
type(msg.type),
|
||||
content(msg.content)
|
||||
{}
|
||||
Message(MessageType t, const std::string& c)
|
||||
: type(t)
|
||||
, content(c)
|
||||
{
|
||||
}
|
||||
Message(const Message& msg)
|
||||
: type(msg.type)
|
||||
, content(msg.content)
|
||||
{
|
||||
}
|
||||
Message& operator=(Message const& msg)
|
||||
{
|
||||
{
|
||||
this->type = msg.type;
|
||||
this->content = msg.content;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<Message> GlobMessages;
|
||||
typedef std::vector<Message>::iterator GlobMessagesIterator;
|
||||
|
||||
public:
|
||||
Glob();
|
||||
~Glob();
|
||||
|
||||
//! Find all files that match the pattern.
|
||||
bool FindFiles(const std::string& inexpr,
|
||||
GlobMessages* messages = 0);
|
||||
bool FindFiles(const std::string& inexpr, GlobMessages* messages = 0);
|
||||
|
||||
//! Return the list of files that matched.
|
||||
std::vector<std::string>& GetFiles();
|
||||
@@ -103,29 +95,27 @@ public:
|
||||
whole strings, but may be disabled to support concatenating
|
||||
expressions more easily (regex1|regex2|etc). */
|
||||
static std::string PatternToRegex(const std::string& pattern,
|
||||
bool require_whole_string = true,
|
||||
bool preserve_case = false);
|
||||
bool require_whole_string = true,
|
||||
bool preserve_case = false);
|
||||
|
||||
/** Getters and setters for enabling and disabling directory
|
||||
listing in recursive and non recursive globbing mode.
|
||||
If listing is enabled in recursive mode it also lists
|
||||
directory symbolic links even if follow symlinks is enabled. */
|
||||
void SetListDirs(bool list) { this->ListDirs=list; }
|
||||
void SetListDirs(bool list) { this->ListDirs = list; }
|
||||
bool GetListDirs() const { return this->ListDirs; }
|
||||
void SetRecurseListDirs(bool list) { this->RecurseListDirs=list; }
|
||||
void SetRecurseListDirs(bool list) { this->RecurseListDirs = list; }
|
||||
bool GetRecurseListDirs() const { return this->RecurseListDirs; }
|
||||
|
||||
protected:
|
||||
//! Process directory
|
||||
void ProcessDirectory(std::string::size_type start,
|
||||
const std::string& dir,
|
||||
GlobMessages* messages);
|
||||
void ProcessDirectory(std::string::size_type start, const std::string& dir,
|
||||
GlobMessages* messages);
|
||||
|
||||
//! Process last directory, but only when recurse flags is on. That is
|
||||
// effectively like saying: /path/to/file/**/file
|
||||
bool RecurseDirectory(std::string::size_type start,
|
||||
const std::string& dir,
|
||||
GlobMessages* messages);
|
||||
bool RecurseDirectory(std::string::size_type start, const std::string& dir,
|
||||
GlobMessages* messages);
|
||||
|
||||
//! Add regular expression
|
||||
void AddExpression(const std::string& expr);
|
||||
@@ -143,8 +133,8 @@ protected:
|
||||
bool RecurseListDirs;
|
||||
|
||||
private:
|
||||
Glob(const Glob&); // Not implemented.
|
||||
void operator=(const Glob&); // Not implemented.
|
||||
Glob(const Glob&); // Not implemented.
|
||||
void operator=(const Glob&); // Not implemented.
|
||||
};
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
+124
-119
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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)
|
||||
|
||||
@@ -19,24 +10,23 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Configure.hxx.in"
|
||||
# include "IOStream.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#include "IOStream.hxx.in"
|
||||
#endif
|
||||
|
||||
// Implement the rest of this file only if it is needed.
|
||||
#if KWSYS_IOS_NEED_OPERATORS_LL
|
||||
|
||||
# include <stdio.h> // sscanf, sprintf
|
||||
# include <string.h> // memchr
|
||||
#include <stdio.h> // sscanf, sprintf
|
||||
#include <string.h> // memchr
|
||||
|
||||
# if defined(_MAX_INT_DIG)
|
||||
# define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
|
||||
# else
|
||||
# define KWSYS_IOS_INT64_MAX_DIG 32
|
||||
# endif
|
||||
#if defined(_MAX_INT_DIG)
|
||||
#define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
|
||||
#else
|
||||
#define KWSYS_IOS_INT64_MAX_DIG 32
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
// Scan an input stream for an integer value.
|
||||
static int IOStreamScanStream(std::istream& is, char* buffer)
|
||||
@@ -46,74 +36,68 @@ static int IOStreamScanStream(std::istream& is, char* buffer)
|
||||
char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1;
|
||||
|
||||
// Look for leading sign.
|
||||
if(is.peek() == '+') { *out++ = '+'; is.ignore(); }
|
||||
else if(is.peek() == '-') { *out++ = '-'; is.ignore(); }
|
||||
if (is.peek() == '+') {
|
||||
*out++ = '+';
|
||||
is.ignore();
|
||||
} else if (is.peek() == '-') {
|
||||
*out++ = '-';
|
||||
is.ignore();
|
||||
}
|
||||
|
||||
// Determine the base. If not specified in the stream, try to
|
||||
// detect it from the input. A leading 0x means hex, and a leading
|
||||
// 0 alone means octal.
|
||||
int base = 0;
|
||||
int flags = is.flags() & std::ios_base::basefield;
|
||||
if(flags == std::ios_base::oct) { base = 8; }
|
||||
else if(flags == std::ios_base::dec) { base = 10; }
|
||||
else if(flags == std::ios_base::hex) { base = 16; }
|
||||
if (flags == std::ios_base::oct) {
|
||||
base = 8;
|
||||
} else if (flags == std::ios_base::dec) {
|
||||
base = 10;
|
||||
} else if (flags == std::ios_base::hex) {
|
||||
base = 16;
|
||||
}
|
||||
bool foundDigit = false;
|
||||
bool foundNonZero = false;
|
||||
if(is.peek() == '0')
|
||||
{
|
||||
if (is.peek() == '0') {
|
||||
foundDigit = true;
|
||||
is.ignore();
|
||||
if((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16))
|
||||
{
|
||||
if ((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16)) {
|
||||
base = 16;
|
||||
foundDigit = false;
|
||||
is.ignore();
|
||||
}
|
||||
else if (base == 0)
|
||||
{
|
||||
} else if (base == 0) {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the range of digits allowed for this number.
|
||||
const char* digits = "0123456789abcdefABCDEF";
|
||||
int maxDigitIndex = 10;
|
||||
if(base == 8)
|
||||
{
|
||||
if (base == 8) {
|
||||
maxDigitIndex = 8;
|
||||
}
|
||||
else if(base == 16)
|
||||
{
|
||||
maxDigitIndex = 10+6+6;
|
||||
}
|
||||
} else if (base == 16) {
|
||||
maxDigitIndex = 10 + 6 + 6;
|
||||
}
|
||||
|
||||
// Scan until an invalid digit is found.
|
||||
for(;is.peek() != EOF; is.ignore())
|
||||
{
|
||||
if(memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0)
|
||||
{
|
||||
if((foundNonZero || *out != '0') && out < end)
|
||||
{
|
||||
for (; is.peek() != EOF; is.ignore()) {
|
||||
if (memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0) {
|
||||
if ((foundNonZero || *out != '0') && out < end) {
|
||||
++out;
|
||||
foundNonZero = true;
|
||||
}
|
||||
}
|
||||
foundDigit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Correct the buffer contents for degenerate cases.
|
||||
if(foundDigit && !foundNonZero)
|
||||
{
|
||||
if (foundDigit && !foundNonZero) {
|
||||
*out++ = '0';
|
||||
}
|
||||
else if (!foundDigit)
|
||||
{
|
||||
} else if (!foundDigit) {
|
||||
out = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate the string in the buffer.
|
||||
*out = '\0';
|
||||
@@ -123,44 +107,54 @@ static int IOStreamScanStream(std::istream& is, char* buffer)
|
||||
|
||||
// Read an integer value from an input stream.
|
||||
template <class T>
|
||||
std::istream&
|
||||
IOStreamScanTemplate(std::istream& is, T& value, char type)
|
||||
std::istream& IOStreamScanTemplate(std::istream& is, T& value, char type)
|
||||
{
|
||||
int state = std::ios_base::goodbit;
|
||||
|
||||
// Skip leading whitespace.
|
||||
std::istream::sentry okay(is);
|
||||
|
||||
if(okay)
|
||||
{
|
||||
if (okay) {
|
||||
try {
|
||||
// Copy the string to a buffer and construct the format string.
|
||||
char buffer[KWSYS_IOS_INT64_MAX_DIG];
|
||||
# if defined(_MSC_VER)
|
||||
char format[] = "%I64_";
|
||||
const int typeIndex = 4;
|
||||
# else
|
||||
char format[] = "%ll_";
|
||||
const int typeIndex = 3;
|
||||
# endif
|
||||
switch(IOStreamScanStream(is, buffer))
|
||||
{
|
||||
case 8: format[typeIndex] = 'o'; break;
|
||||
case 0: // Default to decimal if not told otherwise.
|
||||
case 10: format[typeIndex] = type; break;
|
||||
case 16: format[typeIndex] = 'x'; break;
|
||||
// Copy the string to a buffer and construct the format string.
|
||||
char buffer[KWSYS_IOS_INT64_MAX_DIG];
|
||||
#if defined(_MSC_VER)
|
||||
char format[] = "%I64_";
|
||||
const int typeIndex = 4;
|
||||
#else
|
||||
char format[] = "%ll_";
|
||||
const int typeIndex = 3;
|
||||
#endif
|
||||
switch (IOStreamScanStream(is, buffer)) {
|
||||
case 8:
|
||||
format[typeIndex] = 'o';
|
||||
break;
|
||||
case 0: // Default to decimal if not told otherwise.
|
||||
case 10:
|
||||
format[typeIndex] = type;
|
||||
break;
|
||||
case 16:
|
||||
format[typeIndex] = 'x';
|
||||
break;
|
||||
};
|
||||
|
||||
// Use sscanf to parse the number from the buffer.
|
||||
T result;
|
||||
int success = (sscanf(buffer, format, &result) == 1)?1:0;
|
||||
// Use sscanf to parse the number from the buffer.
|
||||
T result;
|
||||
int success = (sscanf(buffer, format, &result) == 1) ? 1 : 0;
|
||||
|
||||
// Set flags for resulting state.
|
||||
if(is.peek() == EOF) { state |= std::ios_base::eofbit; }
|
||||
if(!success) { state |= std::ios_base::failbit; }
|
||||
else { value = result; }
|
||||
} catch(...) { state |= std::ios_base::badbit; }
|
||||
// Set flags for resulting state.
|
||||
if (is.peek() == EOF) {
|
||||
state |= std::ios_base::eofbit;
|
||||
}
|
||||
if (!success) {
|
||||
state |= std::ios_base::failbit;
|
||||
} else {
|
||||
value = result;
|
||||
}
|
||||
} catch (...) {
|
||||
state |= std::ios_base::badbit;
|
||||
}
|
||||
}
|
||||
|
||||
is.setstate(std::ios_base::iostate(state));
|
||||
return is;
|
||||
@@ -168,42 +162,54 @@ IOStreamScanTemplate(std::istream& is, T& value, char type)
|
||||
|
||||
// Print an integer value to an output stream.
|
||||
template <class T>
|
||||
std::ostream&
|
||||
IOStreamPrintTemplate(std::ostream& os, T value, char type)
|
||||
std::ostream& IOStreamPrintTemplate(std::ostream& os, T value, char type)
|
||||
{
|
||||
std::ostream::sentry okay(os);
|
||||
if(okay)
|
||||
{
|
||||
if (okay) {
|
||||
try {
|
||||
// Construct the format string.
|
||||
char format[8];
|
||||
char* f = format;
|
||||
*f++ = '%';
|
||||
if(os.flags() & std::ios_base::showpos) { *f++ = '+'; }
|
||||
if(os.flags() & std::ios_base::showbase) { *f++ = '#'; }
|
||||
# if defined(_MSC_VER)
|
||||
*f++ = 'I'; *f++ = '6'; *f++ = '4';
|
||||
# else
|
||||
*f++ = 'l'; *f++ = 'l';
|
||||
# endif
|
||||
long bflags = os.flags() & std::ios_base::basefield;
|
||||
if(bflags == std::ios_base::oct) { *f++ = 'o'; }
|
||||
else if(bflags != std::ios_base::hex) { *f++ = type; }
|
||||
else if(os.flags() & std::ios_base::uppercase) { *f++ = 'X'; }
|
||||
else { *f++ = 'x'; }
|
||||
*f = '\0';
|
||||
// Construct the format string.
|
||||
char format[8];
|
||||
char* f = format;
|
||||
*f++ = '%';
|
||||
if (os.flags() & std::ios_base::showpos) {
|
||||
*f++ = '+';
|
||||
}
|
||||
if (os.flags() & std::ios_base::showbase) {
|
||||
*f++ = '#';
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
*f++ = 'I';
|
||||
*f++ = '6';
|
||||
*f++ = '4';
|
||||
#else
|
||||
*f++ = 'l';
|
||||
*f++ = 'l';
|
||||
#endif
|
||||
long bflags = os.flags() & std::ios_base::basefield;
|
||||
if (bflags == std::ios_base::oct) {
|
||||
*f++ = 'o';
|
||||
} else if (bflags != std::ios_base::hex) {
|
||||
*f++ = type;
|
||||
} else if (os.flags() & std::ios_base::uppercase) {
|
||||
*f++ = 'X';
|
||||
} else {
|
||||
*f++ = 'x';
|
||||
}
|
||||
*f = '\0';
|
||||
|
||||
// Use sprintf to print to a buffer and then write the
|
||||
// buffer to the stream.
|
||||
char buffer[2*KWSYS_IOS_INT64_MAX_DIG];
|
||||
sprintf(buffer, format, value);
|
||||
os << buffer;
|
||||
} catch(...) { os.clear(os.rdstate() | std::ios_base::badbit); }
|
||||
// Use sprintf to print to a buffer and then write the
|
||||
// buffer to the stream.
|
||||
char buffer[2 * KWSYS_IOS_INT64_MAX_DIG];
|
||||
sprintf(buffer, format, value);
|
||||
os << buffer;
|
||||
} catch (...) {
|
||||
os.clear(os.rdstate() | std::ios_base::badbit);
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
# if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
|
||||
#if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
|
||||
// Implement input stream operator for IOStreamSLL.
|
||||
std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value)
|
||||
{
|
||||
@@ -215,9 +221,9 @@ std::istream& IOStreamScan(std::istream& is, IOStreamULL& value)
|
||||
{
|
||||
return IOStreamScanTemplate(is, value, 'u');
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
|
||||
#if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
|
||||
// Implement output stream operator for IOStreamSLL.
|
||||
std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value)
|
||||
{
|
||||
@@ -229,14 +235,13 @@ std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value)
|
||||
{
|
||||
return IOStreamPrintTemplate(os, value, 'u');
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
|
||||
#else
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
// Create one public symbol in this object file to avoid warnings from
|
||||
// archivers.
|
||||
|
||||
@@ -1,136 +1,126 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_IOStream_hxx
|
||||
#define @KWSYS_NAMESPACE@_IOStream_hxx
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
/* Define these macros temporarily to keep the code readable. */
|
||||
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
|
||||
/* Whether istream supports long long. */
|
||||
#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_IOS_HAS_ISTREAM_LONG_LONG@
|
||||
#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG \
|
||||
@KWSYS_IOS_HAS_ISTREAM_LONG_LONG@
|
||||
|
||||
/* Whether ostream supports long long. */
|
||||
#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
|
||||
#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG \
|
||||
@KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
|
||||
|
||||
/* Determine whether we need to define the streaming operators for
|
||||
long long or __int64. */
|
||||
#if @KWSYS_USE_LONG_LONG@
|
||||
# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
|
||||
!@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
typedef long long IOStreamSLL;
|
||||
typedef unsigned long long IOStreamULL;
|
||||
}
|
||||
# endif
|
||||
#if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
|
||||
!@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
#define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
typedef long long IOStreamSLL;
|
||||
typedef unsigned long long IOStreamULL;
|
||||
}
|
||||
#endif
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
||||
# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
typedef __int64 IOStreamSLL;
|
||||
typedef unsigned __int64 IOStreamULL;
|
||||
}
|
||||
#define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
typedef __int64 IOStreamSLL;
|
||||
typedef unsigned __int64 IOStreamULL;
|
||||
}
|
||||
#endif
|
||||
#if !defined(@KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL)
|
||||
# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0
|
||||
#define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0
|
||||
#endif
|
||||
|
||||
#if @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
|
||||
# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
|
||||
#if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
|
||||
|
||||
/* Input stream operator implementation functions. */
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&);
|
||||
kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&);
|
||||
}
|
||||
|
||||
/* Provide input stream operator for long long. */
|
||||
# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
|
||||
# define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
|
||||
# define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED
|
||||
inline std::istream&
|
||||
operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
|
||||
#if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
|
||||
#define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
|
||||
#define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED
|
||||
inline std::istream& operator>>(std::istream& is,
|
||||
@KWSYS_NAMESPACE@::IOStreamSLL& value)
|
||||
{
|
||||
return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Provide input stream operator for unsigned long long. */
|
||||
# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
|
||||
# define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
# define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
inline std::istream&
|
||||
operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
|
||||
#if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
|
||||
#define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
#define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
inline std::istream& operator>>(std::istream& is,
|
||||
@KWSYS_NAMESPACE@::IOStreamULL& value)
|
||||
{
|
||||
return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
|
||||
}
|
||||
# endif
|
||||
# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */
|
||||
#endif
|
||||
#endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */
|
||||
|
||||
# if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
#if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
|
||||
/* Output stream operator implementation functions. */
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL);
|
||||
kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL);
|
||||
}
|
||||
|
||||
/* Provide output stream operator for long long. */
|
||||
# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
|
||||
# define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
|
||||
# define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
|
||||
#if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
|
||||
#define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
|
||||
#define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
@KWSYS_NAMESPACE@::IOStreamSLL value)
|
||||
{
|
||||
return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Provide output stream operator for unsigned long long. */
|
||||
# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
|
||||
# define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
# define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
|
||||
#if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) && \
|
||||
!defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
|
||||
#define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
#define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
@KWSYS_NAMESPACE@::IOStreamULL value)
|
||||
{
|
||||
return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
|
||||
}
|
||||
# endif
|
||||
# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */
|
||||
#endif
|
||||
#endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */
|
||||
#endif /* @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL */
|
||||
|
||||
/* Undefine temporary macros. */
|
||||
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysEXPORT
|
||||
#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysEXPORT
|
||||
#endif
|
||||
|
||||
/* If building a C++ file in kwsys itself, give the source file
|
||||
access to the macros without a configured namespace. */
|
||||
#if defined(KWSYS_NAMESPACE)
|
||||
# define KWSYS_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
|
||||
# define KWSYS_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
# define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
|
||||
#define KWSYS_IOS_HAS_ISTREAM_LONG_LONG \
|
||||
@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
|
||||
#define KWSYS_IOS_HAS_OSTREAM_LONG_LONG \
|
||||
@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
#define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+252
-271
@@ -1,26 +1,17 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(MD5.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "MD5.h.in"
|
||||
#include "MD5.h.in"
|
||||
#endif
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memcpy, strlen */
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memcpy, strlen */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -30,8 +21,8 @@
|
||||
implementation file. */
|
||||
|
||||
#if defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-align"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-align"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -97,344 +88,341 @@
|
||||
*/
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
typedef struct md5_state_s
|
||||
{
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define BYTE_ORDER 0
|
||||
#define BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define T_MASK ((md5_word_t)~0)
|
||||
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
|
||||
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
|
||||
#define T3 0x242070db
|
||||
#define T3 0x242070db
|
||||
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
|
||||
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
|
||||
#define T6 0x4787c62a
|
||||
#define T6 0x4787c62a
|
||||
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
|
||||
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
|
||||
#define T9 0x698098d8
|
||||
#define T9 0x698098d8
|
||||
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
|
||||
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
|
||||
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
|
||||
#define T13 0x6b901122
|
||||
#define T13 0x6b901122
|
||||
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
|
||||
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
|
||||
#define T16 0x49b40821
|
||||
#define T16 0x49b40821
|
||||
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
|
||||
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
|
||||
#define T19 0x265e5a51
|
||||
#define T19 0x265e5a51
|
||||
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
|
||||
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
|
||||
#define T22 0x02441453
|
||||
#define T22 0x02441453
|
||||
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
|
||||
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
|
||||
#define T25 0x21e1cde6
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
|
||||
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
|
||||
#define T28 0x455a14ed
|
||||
#define T28 0x455a14ed
|
||||
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
|
||||
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
|
||||
#define T31 0x676f02d9
|
||||
#define T31 0x676f02d9
|
||||
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
|
||||
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
|
||||
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
|
||||
#define T35 0x6d9d6122
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
|
||||
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
|
||||
#define T38 0x4bdecfa9
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
|
||||
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
|
||||
#define T41 0x289b7ec6
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
|
||||
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
|
||||
#define T44 0x04881d05
|
||||
#define T44 0x04881d05
|
||||
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
|
||||
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
|
||||
#define T47 0x1fa27cf8
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
|
||||
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
|
||||
#define T50 0x432aff97
|
||||
#define T50 0x432aff97
|
||||
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
|
||||
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
|
||||
#define T53 0x655b59c3
|
||||
#define T53 0x655b59c3
|
||||
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
|
||||
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
|
||||
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
|
||||
#define T57 0x6fa87e4f
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
|
||||
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
|
||||
#define T60 0x4e0811a1
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
|
||||
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
|
||||
|
||||
|
||||
static void
|
||||
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
|
||||
d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t *X;
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t* X;
|
||||
#endif
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t*)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = (md5_word_t)(xp[0] + (xp[1] << 8) +
|
||||
(xp[2] << 16) + (xp[3] << 24));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t*)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t*)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t* xp = data;
|
||||
int i;
|
||||
|
||||
#if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
#else
|
||||
#define xbuf X /* (static only) */
|
||||
#endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] =
|
||||
(md5_word_t)(xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + F(b,c,d) + X[k] + (Ti);\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + F(b, c, d) + X[k] + (Ti); \
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + G(b,c,d) + X[k] + (Ti);\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + G(b, c, d) + X[k] + (Ti); \
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + H(b,c,d) + X[k] + (Ti);\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + H(b, c, d) + X[k] + (Ti); \
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + I(b,c,d) + X[k] + (Ti);\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + I(b, c, d) + X[k] + (Ti); \
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
static void md5_init(md5_state_t *pms)
|
||||
static void md5_init(md5_state_t* pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* Append a string to the message. */
|
||||
static void md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes)
|
||||
static void md5_append(md5_state_t* pms, const md5_byte_t* data, size_t nbytes)
|
||||
{
|
||||
const md5_byte_t *p = data;
|
||||
size_t left = nbytes;
|
||||
size_t offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
const md5_byte_t* p = data;
|
||||
size_t left = nbytes;
|
||||
size_t offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += (md5_word_t)(nbytes >> 29);
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
/* Update the message length. */
|
||||
pms->count[1] += (md5_word_t)(nbytes >> 29);
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
static void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
static void md5_finish(md5_state_t* pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
|
||||
#if defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma clang diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -449,10 +437,9 @@ kwsysMD5* kwsysMD5_New(void)
|
||||
{
|
||||
/* Allocate a process control structure. */
|
||||
kwsysMD5* md5 = (kwsysMD5*)malloc(sizeof(kwsysMD5));
|
||||
if(!md5)
|
||||
{
|
||||
if (!md5) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
@@ -460,10 +447,9 @@ kwsysMD5* kwsysMD5_New(void)
|
||||
void kwsysMD5_Delete(kwsysMD5* md5)
|
||||
{
|
||||
/* Make sure we have an instance. */
|
||||
if(!md5)
|
||||
{
|
||||
if (!md5) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
free(md5);
|
||||
@@ -479,14 +465,11 @@ void kwsysMD5_Initialize(kwsysMD5* md5)
|
||||
void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length)
|
||||
{
|
||||
size_t dlen;
|
||||
if(length < 0)
|
||||
{
|
||||
if (length < 0) {
|
||||
dlen = strlen((char const*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dlen = (size_t)length;
|
||||
}
|
||||
}
|
||||
md5_append(&md5->md5_state, (md5_byte_t const*)data, dlen);
|
||||
}
|
||||
|
||||
@@ -508,16 +491,14 @@ void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32])
|
||||
void kwsysMD5_DigestToHex(unsigned char const digest[16], char buffer[32])
|
||||
{
|
||||
/* Map from 4-bit index to hexadecimal representation. */
|
||||
static char const hex[16] =
|
||||
{'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
static char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
/* Map each 4-bit block separately. */
|
||||
char* out = buffer;
|
||||
int i;
|
||||
for(i=0; i < 16; ++i)
|
||||
{
|
||||
for (i = 0; i < 16; ++i) {
|
||||
*out++ = hex[digest[i] >> 4];
|
||||
*out++ = hex[digest[i] & 0xF];
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-37
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_MD5_h
|
||||
#define @KWSYS_NAMESPACE@_MD5_h
|
||||
|
||||
@@ -19,24 +10,23 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysMD5 kwsys_ns(MD5)
|
||||
# define kwsysMD5_s kwsys_ns(MD5_s)
|
||||
# define kwsysMD5_New kwsys_ns(MD5_New)
|
||||
# define kwsysMD5_Delete kwsys_ns(MD5_Delete)
|
||||
# define kwsysMD5_Initialize kwsys_ns(MD5_Initialize)
|
||||
# define kwsysMD5_Append kwsys_ns(MD5_Append)
|
||||
# define kwsysMD5_Finalize kwsys_ns(MD5_Finalize)
|
||||
# define kwsysMD5_FinalizeHex kwsys_ns(MD5_FinalizeHex)
|
||||
# define kwsysMD5_DigestToHex kwsys_ns(MD5_DigestToHex)
|
||||
#define kwsysMD5 kwsys_ns(MD5)
|
||||
#define kwsysMD5_s kwsys_ns(MD5_s)
|
||||
#define kwsysMD5_New kwsys_ns(MD5_New)
|
||||
#define kwsysMD5_Delete kwsys_ns(MD5_Delete)
|
||||
#define kwsysMD5_Initialize kwsys_ns(MD5_Initialize)
|
||||
#define kwsysMD5_Append kwsys_ns(MD5_Append)
|
||||
#define kwsysMD5_Finalize kwsys_ns(MD5_Finalize)
|
||||
#define kwsysMD5_FinalizeHex kwsys_ns(MD5_FinalizeHex)
|
||||
#define kwsysMD5_DigestToHex kwsys_ns(MD5_DigestToHex)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -89,19 +79,19 @@ kwsysEXPORT void kwsysMD5_DigestToHex(unsigned char const digest[16],
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysMD5
|
||||
# undef kwsysMD5_s
|
||||
# undef kwsysMD5_New
|
||||
# undef kwsysMD5_Delete
|
||||
# undef kwsysMD5_Initialize
|
||||
# undef kwsysMD5_Append
|
||||
# undef kwsysMD5_Finalize
|
||||
# undef kwsysMD5_FinalizeHex
|
||||
# undef kwsysMD5_DigestToHex
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysMD5
|
||||
#undef kwsysMD5_s
|
||||
#undef kwsysMD5_New
|
||||
#undef kwsysMD5_Delete
|
||||
#undef kwsysMD5_Initialize
|
||||
#undef kwsysMD5_Append
|
||||
#undef kwsysMD5_Finalize
|
||||
#undef kwsysMD5_FinalizeHex
|
||||
#undef kwsysMD5_DigestToHex
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+127
-133
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Process_h
|
||||
#define @KWSYS_NAMESPACE@_Process_h
|
||||
|
||||
@@ -19,70 +10,70 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysProcess kwsys_ns(Process)
|
||||
# define kwsysProcess_s kwsys_ns(Process_s)
|
||||
# define kwsysProcess_New kwsys_ns(Process_New)
|
||||
# define kwsysProcess_Delete kwsys_ns(Process_Delete)
|
||||
# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
|
||||
# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
|
||||
# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
|
||||
# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
|
||||
# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
|
||||
# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
|
||||
# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
|
||||
# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
|
||||
# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
|
||||
# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
|
||||
# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
|
||||
# define kwsysProcess_Option_CreateProcessGroup kwsys_ns(Process_Option_CreateProcessGroup)
|
||||
# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
|
||||
# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
|
||||
# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
|
||||
# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
|
||||
# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
|
||||
# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
|
||||
# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
|
||||
# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
|
||||
# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
|
||||
# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
|
||||
# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
|
||||
# define kwsysProcess_GetState kwsys_ns(Process_GetState)
|
||||
# define kwsysProcess_State_e kwsys_ns(Process_State_e)
|
||||
# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
|
||||
# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
|
||||
# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
|
||||
# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
|
||||
# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
|
||||
# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
|
||||
# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
|
||||
# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
|
||||
# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
|
||||
# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
|
||||
# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
|
||||
# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
|
||||
# define kwsysProcess_Execute kwsys_ns(Process_Execute)
|
||||
# define kwsysProcess_Disown kwsys_ns(Process_Disown)
|
||||
# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
|
||||
# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
|
||||
# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
|
||||
# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
|
||||
# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
|
||||
# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
|
||||
# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
|
||||
# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
|
||||
# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
|
||||
# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
|
||||
# define kwsysProcess_Kill kwsys_ns(Process_Kill)
|
||||
# define kwsysProcess_ResetStartTime kwsys_ns(Process_ResetStartTime)
|
||||
#define kwsysProcess kwsys_ns(Process)
|
||||
#define kwsysProcess_s kwsys_ns(Process_s)
|
||||
#define kwsysProcess_New kwsys_ns(Process_New)
|
||||
#define kwsysProcess_Delete kwsys_ns(Process_Delete)
|
||||
#define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
|
||||
#define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
|
||||
#define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
|
||||
#define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
|
||||
#define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
|
||||
#define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
|
||||
#define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
|
||||
#define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
|
||||
#define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
|
||||
#define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
|
||||
#define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
|
||||
#define kwsysProcess_Option_CreateProcessGroup \
|
||||
kwsys_ns(Process_Option_CreateProcessGroup)
|
||||
#define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
|
||||
#define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
|
||||
#define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
|
||||
#define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
|
||||
#define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
|
||||
#define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
|
||||
#define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
|
||||
#define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
|
||||
#define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
|
||||
#define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
|
||||
#define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
|
||||
#define kwsysProcess_GetState kwsys_ns(Process_GetState)
|
||||
#define kwsysProcess_State_e kwsys_ns(Process_State_e)
|
||||
#define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
|
||||
#define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
|
||||
#define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
|
||||
#define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
|
||||
#define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
|
||||
#define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
|
||||
#define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
|
||||
#define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
|
||||
#define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
|
||||
#define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
|
||||
#define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
|
||||
#define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
|
||||
#define kwsysProcess_Execute kwsys_ns(Process_Execute)
|
||||
#define kwsysProcess_Disown kwsys_ns(Process_Disown)
|
||||
#define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
|
||||
#define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
|
||||
#define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
|
||||
#define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
|
||||
#define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
|
||||
#define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
|
||||
#define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
|
||||
#define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
|
||||
#define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
|
||||
#define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
|
||||
#define kwsysProcess_Kill kwsys_ns(Process_Kill)
|
||||
#define kwsysProcess_ResetStartTime kwsys_ns(Process_ResetStartTime)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -256,9 +247,12 @@ enum kwsysProcess_State_e
|
||||
*
|
||||
* kwsysProcess_Exception_None = No exceptional behavior occurred.
|
||||
* kwsysProcess_Exception_Fault = Child crashed with a memory fault.
|
||||
* kwsysProcess_Exception_Illegal = Child crashed with an illegal instruction.
|
||||
* kwsysProcess_Exception_Interrupt = Child was interrupted by user (Cntl-C/Break).
|
||||
* kwsysProcess_Exception_Numerical = Child crashed with a numerical exception.
|
||||
* kwsysProcess_Exception_Illegal = Child crashed with an illegal
|
||||
* instruction.
|
||||
* kwsysProcess_Exception_Interrupt = Child was interrupted by user
|
||||
* (Cntl-C/Break).
|
||||
* kwsysProcess_Exception_Numerical = Child crashed with a numerical
|
||||
* exception.
|
||||
* kwsysProcess_Exception_Other = Child terminated for another reason.
|
||||
*/
|
||||
kwsysEXPORT int kwsysProcess_GetExitException(kwsysProcess* cp);
|
||||
@@ -352,7 +346,7 @@ enum kwsysProcess_Pipes_e
|
||||
kwsysProcess_Pipe_STDIN,
|
||||
kwsysProcess_Pipe_STDOUT,
|
||||
kwsysProcess_Pipe_STDERR,
|
||||
kwsysProcess_Pipe_Timeout=255
|
||||
kwsysProcess_Pipe_Timeout = 255
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -405,65 +399,65 @@ kwsysEXPORT void kwsysProcess_ResetStartTime(kwsysProcess* cp);
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysProcess
|
||||
# undef kwsysProcess_s
|
||||
# undef kwsysProcess_New
|
||||
# undef kwsysProcess_Delete
|
||||
# undef kwsysProcess_SetCommand
|
||||
# undef kwsysProcess_AddCommand
|
||||
# undef kwsysProcess_SetTimeout
|
||||
# undef kwsysProcess_SetWorkingDirectory
|
||||
# undef kwsysProcess_SetPipeFile
|
||||
# undef kwsysProcess_SetPipeNative
|
||||
# undef kwsysProcess_SetPipeShared
|
||||
# undef kwsysProcess_Option_Detach
|
||||
# undef kwsysProcess_Option_HideWindow
|
||||
# undef kwsysProcess_Option_MergeOutput
|
||||
# undef kwsysProcess_Option_Verbatim
|
||||
# undef kwsysProcess_Option_CreateProcessGroup
|
||||
# undef kwsysProcess_GetOption
|
||||
# undef kwsysProcess_SetOption
|
||||
# undef kwsysProcess_Option_e
|
||||
# undef kwsysProcess_State_Starting
|
||||
# undef kwsysProcess_State_Error
|
||||
# undef kwsysProcess_State_Exception
|
||||
# undef kwsysProcess_State_Executing
|
||||
# undef kwsysProcess_State_Exited
|
||||
# undef kwsysProcess_State_Expired
|
||||
# undef kwsysProcess_State_Killed
|
||||
# undef kwsysProcess_State_Disowned
|
||||
# undef kwsysProcess_GetState
|
||||
# undef kwsysProcess_State_e
|
||||
# undef kwsysProcess_Exception_None
|
||||
# undef kwsysProcess_Exception_Fault
|
||||
# undef kwsysProcess_Exception_Illegal
|
||||
# undef kwsysProcess_Exception_Interrupt
|
||||
# undef kwsysProcess_Exception_Numerical
|
||||
# undef kwsysProcess_Exception_Other
|
||||
# undef kwsysProcess_GetExitException
|
||||
# undef kwsysProcess_Exception_e
|
||||
# undef kwsysProcess_GetExitCode
|
||||
# undef kwsysProcess_GetExitValue
|
||||
# undef kwsysProcess_GetErrorString
|
||||
# undef kwsysProcess_GetExceptionString
|
||||
# undef kwsysProcess_Execute
|
||||
# undef kwsysProcess_Disown
|
||||
# undef kwsysProcess_WaitForData
|
||||
# undef kwsysProcess_Pipes_e
|
||||
# undef kwsysProcess_Pipe_None
|
||||
# undef kwsysProcess_Pipe_STDIN
|
||||
# undef kwsysProcess_Pipe_STDOUT
|
||||
# undef kwsysProcess_Pipe_STDERR
|
||||
# undef kwsysProcess_Pipe_Timeout
|
||||
# undef kwsysProcess_Pipe_Handle
|
||||
# undef kwsysProcess_WaitForExit
|
||||
# undef kwsysProcess_Interrupt
|
||||
# undef kwsysProcess_Kill
|
||||
# undef kwsysProcess_ResetStartTime
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysProcess
|
||||
#undef kwsysProcess_s
|
||||
#undef kwsysProcess_New
|
||||
#undef kwsysProcess_Delete
|
||||
#undef kwsysProcess_SetCommand
|
||||
#undef kwsysProcess_AddCommand
|
||||
#undef kwsysProcess_SetTimeout
|
||||
#undef kwsysProcess_SetWorkingDirectory
|
||||
#undef kwsysProcess_SetPipeFile
|
||||
#undef kwsysProcess_SetPipeNative
|
||||
#undef kwsysProcess_SetPipeShared
|
||||
#undef kwsysProcess_Option_Detach
|
||||
#undef kwsysProcess_Option_HideWindow
|
||||
#undef kwsysProcess_Option_MergeOutput
|
||||
#undef kwsysProcess_Option_Verbatim
|
||||
#undef kwsysProcess_Option_CreateProcessGroup
|
||||
#undef kwsysProcess_GetOption
|
||||
#undef kwsysProcess_SetOption
|
||||
#undef kwsysProcess_Option_e
|
||||
#undef kwsysProcess_State_Starting
|
||||
#undef kwsysProcess_State_Error
|
||||
#undef kwsysProcess_State_Exception
|
||||
#undef kwsysProcess_State_Executing
|
||||
#undef kwsysProcess_State_Exited
|
||||
#undef kwsysProcess_State_Expired
|
||||
#undef kwsysProcess_State_Killed
|
||||
#undef kwsysProcess_State_Disowned
|
||||
#undef kwsysProcess_GetState
|
||||
#undef kwsysProcess_State_e
|
||||
#undef kwsysProcess_Exception_None
|
||||
#undef kwsysProcess_Exception_Fault
|
||||
#undef kwsysProcess_Exception_Illegal
|
||||
#undef kwsysProcess_Exception_Interrupt
|
||||
#undef kwsysProcess_Exception_Numerical
|
||||
#undef kwsysProcess_Exception_Other
|
||||
#undef kwsysProcess_GetExitException
|
||||
#undef kwsysProcess_Exception_e
|
||||
#undef kwsysProcess_GetExitCode
|
||||
#undef kwsysProcess_GetExitValue
|
||||
#undef kwsysProcess_GetErrorString
|
||||
#undef kwsysProcess_GetExceptionString
|
||||
#undef kwsysProcess_Execute
|
||||
#undef kwsysProcess_Disown
|
||||
#undef kwsysProcess_WaitForData
|
||||
#undef kwsysProcess_Pipes_e
|
||||
#undef kwsysProcess_Pipe_None
|
||||
#undef kwsysProcess_Pipe_STDIN
|
||||
#undef kwsysProcess_Pipe_STDOUT
|
||||
#undef kwsysProcess_Pipe_STDERR
|
||||
#undef kwsysProcess_Pipe_Timeout
|
||||
#undef kwsysProcess_Pipe_Handle
|
||||
#undef kwsysProcess_WaitForExit
|
||||
#undef kwsysProcess_Interrupt
|
||||
#undef kwsysProcess_Kill
|
||||
#undef kwsysProcess_ResetStartTime
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+948
-1124
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Process.h)
|
||||
#include KWSYS_HEADER(System.h)
|
||||
@@ -16,8 +7,8 @@
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Process.h.in"
|
||||
# include "System.h.in"
|
||||
#include "Process.h.in"
|
||||
#include "System.h.in"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -35,7 +26,6 @@ races.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
@@ -50,30 +40,30 @@ do.
|
||||
#if defined(__CYGWIN__)
|
||||
/* Increase the file descriptor limit for select() before including
|
||||
related system headers. (Default: 64) */
|
||||
# define FD_SETSIZE 16384
|
||||
#define FD_SETSIZE 16384
|
||||
#endif
|
||||
|
||||
#include <assert.h> /* assert */
|
||||
#include <ctype.h> /* isspace */
|
||||
#include <dirent.h> /* DIR, dirent */
|
||||
#include <errno.h> /* errno */
|
||||
#include <fcntl.h> /* fcntl */
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
#include <stdio.h> /* snprintf */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* strdup, strerror, memset */
|
||||
#include <sys/stat.h> /* open mode */
|
||||
#include <sys/time.h> /* struct timeval */
|
||||
#include <sys/types.h> /* pid_t, fd_set */
|
||||
#include <sys/wait.h> /* waitpid */
|
||||
#include <sys/stat.h> /* open mode */
|
||||
#include <unistd.h> /* pipe, close, fork, execvp, select, _exit */
|
||||
#include <fcntl.h> /* fcntl */
|
||||
#include <errno.h> /* errno */
|
||||
#include <time.h> /* gettimeofday */
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <dirent.h> /* DIR, dirent */
|
||||
#include <ctype.h> /* isspace */
|
||||
#include <assert.h> /* assert */
|
||||
#include <unistd.h> /* pipe, close, fork, execvp, select, _exit */
|
||||
|
||||
#if defined(__VMS)
|
||||
# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
|
||||
#define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
|
||||
#else
|
||||
# define KWSYSPE_VMS_NONBLOCK
|
||||
#define KWSYSPE_VMS_NONBLOCK
|
||||
#endif
|
||||
|
||||
#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
|
||||
@@ -90,13 +80,13 @@ typedef int kwsysProcess_ssize_t;
|
||||
|
||||
#if defined(__BEOS__) && !defined(__ZETA__)
|
||||
/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
|
||||
# include <be/kernel/OS.h>
|
||||
#include <be/kernel/OS.h>
|
||||
static inline void kwsysProcess_usleep(unsigned int msec)
|
||||
{
|
||||
snooze(msec);
|
||||
}
|
||||
#else
|
||||
# define kwsysProcess_usleep usleep
|
||||
#define kwsysProcess_usleep usleep
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -110,12 +100,12 @@ static inline void kwsysProcess_usleep(unsigned int msec)
|
||||
* without select().
|
||||
*/
|
||||
#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__)
|
||||
# define KWSYSPE_USE_SELECT 1
|
||||
#define KWSYSPE_USE_SELECT 1
|
||||
#endif
|
||||
|
||||
/* Some platforms do not have siginfo on their signal handlers. */
|
||||
#if defined(SA_SIGINFO) && !defined(__BEOS__)
|
||||
# define KWSYSPE_USE_SIGINFO 1
|
||||
#define KWSYSPE_USE_SIGINFO 1
|
||||
#endif
|
||||
|
||||
/* The number of pipes for the child's output. The standard stdout
|
||||
@@ -172,8 +162,10 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
|
||||
static double kwsysProcessTimeToDouble(kwsysProcessTime t);
|
||||
static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
|
||||
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2);
|
||||
static void kwsysProcessSetExitException(kwsysProcess* cp, int sig);
|
||||
static void kwsysProcessChildErrorExit(int errorPipe);
|
||||
static void kwsysProcessRestoreDefaultSignalHandlers(void);
|
||||
@@ -281,10 +273,10 @@ struct kwsysProcess_s
|
||||
volatile sig_atomic_t Killed;
|
||||
|
||||
/* Buffer for error message in case of failure. */
|
||||
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1];
|
||||
|
||||
/* Description for the ExitException. */
|
||||
char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1];
|
||||
|
||||
/* The exit codes of each child process in the pipeline. */
|
||||
int* CommandExitCodes;
|
||||
@@ -314,10 +306,9 @@ kwsysProcess* kwsysProcess_New(void)
|
||||
{
|
||||
/* Allocate a process control structure. */
|
||||
kwsysProcess* cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memset(cp, 0, sizeof(kwsysProcess));
|
||||
|
||||
/* Share stdin with the parent process by default. */
|
||||
@@ -341,23 +332,18 @@ kwsysProcess* kwsysProcess_New(void)
|
||||
void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
{
|
||||
/* Make sure we have an instance. */
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the process is executing, wait for it to finish. */
|
||||
if(cp->State == kwsysProcess_State_Executing)
|
||||
{
|
||||
if(cp->Detached)
|
||||
{
|
||||
if (cp->State == kwsysProcess_State_Executing) {
|
||||
if (cp->Detached) {
|
||||
kwsysProcess_Disown(cp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
kwsysProcess_WaitForExit(cp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
kwsysProcess_SetCommand(cp, 0);
|
||||
@@ -365,10 +351,9 @@ 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)
|
||||
{
|
||||
if (cp->CommandExitCodes) {
|
||||
free(cp->CommandExitCodes);
|
||||
}
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
|
||||
@@ -376,29 +361,24 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
|
||||
{
|
||||
int i;
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
char** c = cp->Commands[i];
|
||||
while(*c)
|
||||
{
|
||||
while (*c) {
|
||||
free(*c++);
|
||||
}
|
||||
free(cp->Commands[i]);
|
||||
}
|
||||
free(cp->Commands[i]);
|
||||
}
|
||||
cp->NumberOfCommands = 0;
|
||||
if(cp->Commands)
|
||||
{
|
||||
if (cp->Commands) {
|
||||
free(cp->Commands);
|
||||
cp->Commands = 0;
|
||||
}
|
||||
if(command)
|
||||
{
|
||||
}
|
||||
if (command) {
|
||||
return kwsysProcess_AddCommand(cp, command);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -409,81 +389,70 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
||||
char*** newCommands;
|
||||
|
||||
/* Make sure we have a command to add. */
|
||||
if(!cp || !command || !*command)
|
||||
{
|
||||
if (!cp || !command || !*command) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate a new array for command pointers. */
|
||||
newNumberOfCommands = cp->NumberOfCommands + 1;
|
||||
if(!(newCommands =
|
||||
(char***)malloc(sizeof(char**) *(size_t)(newNumberOfCommands))))
|
||||
{
|
||||
if (!(newCommands =
|
||||
(char***)malloc(sizeof(char**) * (size_t)(newNumberOfCommands)))) {
|
||||
/* Out of memory. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy any existing commands into the new array. */
|
||||
{
|
||||
int i;
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
newCommands[i] = cp->Commands[i];
|
||||
int i;
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
newCommands[i] = cp->Commands[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the new command. */
|
||||
if(cp->Verbatim)
|
||||
{
|
||||
if (cp->Verbatim) {
|
||||
/* In order to run the given command line verbatim we need to
|
||||
parse it. */
|
||||
newCommands[cp->NumberOfCommands] =
|
||||
kwsysSystem_Parse_CommandForUnix(*command, 0);
|
||||
if(!newCommands[cp->NumberOfCommands] ||
|
||||
!newCommands[cp->NumberOfCommands][0])
|
||||
{
|
||||
if (!newCommands[cp->NumberOfCommands] ||
|
||||
!newCommands[cp->NumberOfCommands][0]) {
|
||||
/* Out of memory or no command parsed. */
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Copy each argument string individually. */
|
||||
char const* const* c = command;
|
||||
kwsysProcess_ptrdiff_t n = 0;
|
||||
kwsysProcess_ptrdiff_t i = 0;
|
||||
while(*c++);
|
||||
while (*c++)
|
||||
;
|
||||
n = c - command - 1;
|
||||
newCommands[cp->NumberOfCommands] =
|
||||
(char**)malloc((size_t)(n+1)*sizeof(char*));
|
||||
if(!newCommands[cp->NumberOfCommands])
|
||||
{
|
||||
(char**)malloc((size_t)(n + 1) * sizeof(char*));
|
||||
if (!newCommands[cp->NumberOfCommands]) {
|
||||
/* Out of memory. */
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i < n; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
assert(command[i]); /* Quiet Clang scan-build. */
|
||||
newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
|
||||
if(!newCommands[cp->NumberOfCommands][i])
|
||||
{
|
||||
if (!newCommands[cp->NumberOfCommands][i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < n)
|
||||
{
|
||||
}
|
||||
if (i < n) {
|
||||
/* Out of memory. */
|
||||
for(;i > 0; --i)
|
||||
{
|
||||
free(newCommands[cp->NumberOfCommands][i-1]);
|
||||
}
|
||||
for (; i > 0; --i) {
|
||||
free(newCommands[cp->NumberOfCommands][i - 1]);
|
||||
}
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
newCommands[cp->NumberOfCommands][n] = 0;
|
||||
}
|
||||
newCommands[cp->NumberOfCommands][n] = 0;
|
||||
}
|
||||
|
||||
/* Successfully allocated new command array. Free the old array. */
|
||||
free(cp->Commands);
|
||||
@@ -496,15 +465,13 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cp->Timeout = timeout;
|
||||
if(cp->Timeout < 0)
|
||||
{
|
||||
if (cp->Timeout < 0) {
|
||||
cp->Timeout = 0;
|
||||
}
|
||||
}
|
||||
// Force recomputation of TimeoutTime.
|
||||
cp->TimeoutTime.tv_sec = -1;
|
||||
}
|
||||
@@ -512,32 +479,26 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
if(cp->WorkingDirectory == dir)
|
||||
{
|
||||
}
|
||||
if (cp->WorkingDirectory == dir) {
|
||||
return 1;
|
||||
}
|
||||
if(cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0)
|
||||
{
|
||||
}
|
||||
if (cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if(cp->WorkingDirectory)
|
||||
{
|
||||
}
|
||||
if (cp->WorkingDirectory) {
|
||||
free(cp->WorkingDirectory);
|
||||
cp->WorkingDirectory = 0;
|
||||
}
|
||||
if(dir)
|
||||
{
|
||||
}
|
||||
if (dir) {
|
||||
cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
|
||||
if(!cp->WorkingDirectory)
|
||||
{
|
||||
if (!cp->WorkingDirectory) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(cp->WorkingDirectory, dir);
|
||||
}
|
||||
strcpy(cp->WorkingDirectory, dir);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -545,65 +506,70 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
|
||||
int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
|
||||
{
|
||||
char** pfile;
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
switch(prPipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
|
||||
case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
|
||||
case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
|
||||
default: return 0;
|
||||
}
|
||||
if(*pfile)
|
||||
{
|
||||
}
|
||||
switch (prPipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
pfile = &cp->PipeFileSTDIN;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
pfile = &cp->PipeFileSTDOUT;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
pfile = &cp->PipeFileSTDERR;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (*pfile) {
|
||||
free(*pfile);
|
||||
*pfile = 0;
|
||||
}
|
||||
if(file)
|
||||
{
|
||||
*pfile = (char*)malloc(strlen(file)+1);
|
||||
if(!*pfile)
|
||||
{
|
||||
}
|
||||
if (file) {
|
||||
*pfile = (char*)malloc(strlen(file) + 1);
|
||||
if (!*pfile) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(*pfile, file);
|
||||
}
|
||||
strcpy(*pfile, file);
|
||||
}
|
||||
|
||||
/* If we are redirecting the pipe, do not share it or use a native
|
||||
pipe. */
|
||||
if(*pfile)
|
||||
{
|
||||
if (*pfile) {
|
||||
kwsysProcess_SetPipeNative(cp, prPipe, 0);
|
||||
kwsysProcess_SetPipeShared(cp, prPipe, 0);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(prPipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
|
||||
case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
|
||||
case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
|
||||
default: return;
|
||||
}
|
||||
switch (prPipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
cp->PipeSharedSTDIN = shared ? 1 : 0;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
cp->PipeSharedSTDOUT = shared ? 1 : 0;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
cp->PipeSharedSTDERR = shared ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we are sharing the pipe, do not redirect it to a file or use a
|
||||
native pipe. */
|
||||
if(shared)
|
||||
{
|
||||
if (shared) {
|
||||
kwsysProcess_SetPipeFile(cp, prPipe, 0);
|
||||
kwsysProcess_SetPipeNative(cp, prPipe, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -611,127 +577,130 @@ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
|
||||
{
|
||||
int* pPipeNative = 0;
|
||||
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(prPipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
|
||||
case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
|
||||
case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
|
||||
default: return;
|
||||
}
|
||||
switch (prPipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
pPipeNative = cp->PipeNativeSTDIN;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
pPipeNative = cp->PipeNativeSTDOUT;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
pPipeNative = cp->PipeNativeSTDERR;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the native pipe descriptors provided. */
|
||||
if(p)
|
||||
{
|
||||
if (p) {
|
||||
pPipeNative[0] = p[0];
|
||||
pPipeNative[1] = p[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pPipeNative[0] = -1;
|
||||
pPipeNative[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are using a native pipe, do not share it or redirect it to
|
||||
a file. */
|
||||
if(p)
|
||||
{
|
||||
if (p) {
|
||||
kwsysProcess_SetPipeFile(cp, prPipe, 0);
|
||||
kwsysProcess_SetPipeShared(cp, prPipe, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(optionId)
|
||||
{
|
||||
case kwsysProcess_Option_Detach: return cp->OptionDetach;
|
||||
case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
|
||||
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
|
||||
switch (optionId) {
|
||||
case kwsysProcess_Option_Detach:
|
||||
return cp->OptionDetach;
|
||||
case kwsysProcess_Option_MergeOutput:
|
||||
return cp->MergeOutput;
|
||||
case kwsysProcess_Option_Verbatim:
|
||||
return cp->Verbatim;
|
||||
case kwsysProcess_Option_CreateProcessGroup:
|
||||
return cp->CreateProcessGroup;
|
||||
default: return 0;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(optionId)
|
||||
{
|
||||
case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
|
||||
case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
|
||||
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
|
||||
switch (optionId) {
|
||||
case kwsysProcess_Option_Detach:
|
||||
cp->OptionDetach = value;
|
||||
break;
|
||||
case kwsysProcess_Option_MergeOutput:
|
||||
cp->MergeOutput = value;
|
||||
break;
|
||||
case kwsysProcess_Option_Verbatim:
|
||||
cp->Verbatim = value;
|
||||
break;
|
||||
case kwsysProcess_Option_CreateProcessGroup:
|
||||
cp->CreateProcessGroup = value; break;
|
||||
default: break;
|
||||
}
|
||||
cp->CreateProcessGroup = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetState(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->State : kwsysProcess_State_Error;
|
||||
return cp ? cp->State : kwsysProcess_State_Error;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitException(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitException : kwsysProcess_Exception_Other;
|
||||
return cp ? cp->ExitException : kwsysProcess_Exception_Other;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitCode(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitCode : 0;
|
||||
return cp ? cp->ExitCode : 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitValue(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitValue : -1;
|
||||
return cp ? cp->ExitValue : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return "Process management structure could not be allocated";
|
||||
}
|
||||
else if(cp->State == kwsysProcess_State_Error)
|
||||
{
|
||||
} else if (cp->State == kwsysProcess_State_Error) {
|
||||
return cp->ErrorMessage;
|
||||
}
|
||||
}
|
||||
return "Success";
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return "GetExceptionString called with NULL process management structure";
|
||||
}
|
||||
else if(cp->State == kwsysProcess_State_Exception)
|
||||
{
|
||||
} else if (cp->State == kwsysProcess_State_Exception) {
|
||||
return cp->ExitExceptionString;
|
||||
}
|
||||
}
|
||||
return "No exception";
|
||||
}
|
||||
|
||||
@@ -741,231 +710,193 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Do not execute a second copy simultaneously. */
|
||||
if(!cp || cp->State == kwsysProcess_State_Executing)
|
||||
{
|
||||
if (!cp || cp->State == kwsysProcess_State_Executing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have something to run. */
|
||||
if(cp->NumberOfCommands < 1)
|
||||
{
|
||||
if (cp->NumberOfCommands < 1) {
|
||||
strcpy(cp->ErrorMessage, "No command");
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the control structure for a new process. */
|
||||
if(!kwsysProcessInitialize(cp))
|
||||
{
|
||||
if (!kwsysProcessInitialize(cp)) {
|
||||
strcpy(cp->ErrorMessage, "Out of memory");
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__VMS)
|
||||
/* Make sure pipes behave like streams on VMS. */
|
||||
if(!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1))
|
||||
{
|
||||
if (!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save the real working directory of this process and change to
|
||||
the working directory for the child processes. This is needed
|
||||
to make pipe file paths evaluate correctly. */
|
||||
if(cp->WorkingDirectory)
|
||||
{
|
||||
if (cp->WorkingDirectory) {
|
||||
int r;
|
||||
if(!getcwd(cp->RealWorkingDirectory,
|
||||
(size_t)(cp->RealWorkingDirectoryLength)))
|
||||
{
|
||||
if (!getcwd(cp->RealWorkingDirectory,
|
||||
(size_t)(cp->RealWorkingDirectoryLength))) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some platforms specify that the chdir call may be
|
||||
interrupted. Repeat the call until it finishes. */
|
||||
while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
|
||||
if(r < 0)
|
||||
{
|
||||
while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR))
|
||||
;
|
||||
if (r < 0) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If not running a detached child, add this object to the global
|
||||
set of process objects that wish to be notified when a child
|
||||
exits. */
|
||||
if(!cp->OptionDetach)
|
||||
{
|
||||
if(!kwsysProcessesAdd(cp))
|
||||
{
|
||||
if (!cp->OptionDetach) {
|
||||
if (!kwsysProcessesAdd(cp)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the stdin pipe for the first process. */
|
||||
if(cp->PipeFileSTDIN)
|
||||
{
|
||||
if (cp->PipeFileSTDIN) {
|
||||
/* Open a file for the child's stdin to read. */
|
||||
cp->PipeChildStd[0] = open(cp->PipeFileSTDIN, O_RDONLY);
|
||||
if(cp->PipeChildStd[0] < 0)
|
||||
{
|
||||
if (cp->PipeChildStd[0] < 0) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag on the pipe's end. */
|
||||
if(fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0)
|
||||
{
|
||||
if (fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(cp->PipeSharedSTDIN)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDIN) {
|
||||
cp->PipeChildStd[0] = 0;
|
||||
}
|
||||
else if(cp->PipeNativeSTDIN[0] >= 0)
|
||||
{
|
||||
} else if (cp->PipeNativeSTDIN[0] >= 0) {
|
||||
cp->PipeChildStd[0] = cp->PipeNativeSTDIN[0];
|
||||
|
||||
/* Set close-on-exec flag on the pipe's ends. The read end will
|
||||
be dup2-ed into the stdin descriptor after the fork but before
|
||||
the exec. */
|
||||
if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
if ((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cp->PipeChildStd[0] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the output pipe for the last process.
|
||||
We always create this so the pipe can be passed to select even if
|
||||
it will report closed immediately. */
|
||||
{
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the pipe. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0];
|
||||
cp->PipeChildStd[1] = p[1];
|
||||
/* Store the pipe. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0];
|
||||
cp->PipeChildStd[1] = p[1];
|
||||
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set to non-blocking in case select lies, or for the polling
|
||||
implementation. */
|
||||
if(!kwsysProcessSetNonBlocking(p[0]))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Set to non-blocking in case select lies, or for the polling
|
||||
implementation. */
|
||||
if (!kwsysProcessSetNonBlocking(p[0])) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cp->PipeFileSTDOUT)
|
||||
{
|
||||
if (cp->PipeFileSTDOUT) {
|
||||
/* Use a file for stdout. */
|
||||
if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
|
||||
cp->PipeFileSTDOUT))
|
||||
{
|
||||
if (!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
|
||||
cp->PipeFileSTDOUT)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (cp->PipeSharedSTDOUT)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDOUT) {
|
||||
/* Use the parent stdout. */
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeChildStd[1]);
|
||||
cp->PipeChildStd[1] = 1;
|
||||
}
|
||||
else if (cp->PipeNativeSTDOUT[1] >= 0)
|
||||
{
|
||||
} else if (cp->PipeNativeSTDOUT[1] >= 0) {
|
||||
/* Use the given descriptor for stdout. */
|
||||
if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1],
|
||||
cp->PipeNativeSTDOUT))
|
||||
{
|
||||
if (!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1],
|
||||
cp->PipeNativeSTDOUT)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create stderr pipe to be shared by all processes in the pipeline.
|
||||
We always create this so the pipe can be passed to select even if
|
||||
it will report closed immediately. */
|
||||
{
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the pipe. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
|
||||
cp->PipeChildStd[2] = p[1];
|
||||
/* Store the pipe. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
|
||||
cp->PipeChildStd[2] = p[1];
|
||||
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set to non-blocking in case select lies, or for the polling
|
||||
implementation. */
|
||||
if(!kwsysProcessSetNonBlocking(p[0]))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
/* Set to non-blocking in case select lies, or for the polling
|
||||
implementation. */
|
||||
if (!kwsysProcessSetNonBlocking(p[0])) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cp->PipeFileSTDERR)
|
||||
{
|
||||
if (cp->PipeFileSTDERR) {
|
||||
/* Use a file for stderr. */
|
||||
if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
|
||||
cp->PipeFileSTDERR))
|
||||
{
|
||||
if (!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
|
||||
cp->PipeFileSTDERR)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (cp->PipeSharedSTDERR)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDERR) {
|
||||
/* Use the parent stderr. */
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeChildStd[2]);
|
||||
cp->PipeChildStd[2] = 2;
|
||||
}
|
||||
else if (cp->PipeNativeSTDERR[1] >= 0)
|
||||
{
|
||||
} else if (cp->PipeNativeSTDERR[1] >= 0) {
|
||||
/* Use the given handle for stderr. */
|
||||
if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2],
|
||||
cp->PipeNativeSTDERR))
|
||||
{
|
||||
if (!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2],
|
||||
cp->PipeNativeSTDERR)) {
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The timeout period starts now. */
|
||||
cp->StartTime = kwsysProcessTimeGetCurrent();
|
||||
@@ -974,96 +905,82 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
||||
|
||||
/* Create the pipeline of processes. */
|
||||
{
|
||||
kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
|
||||
int nextStdIn = cp->PipeChildStd[0];
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
/* Setup the process's pipes. */
|
||||
si.StdIn = nextStdIn;
|
||||
if (i == cp->NumberOfCommands-1)
|
||||
{
|
||||
nextStdIn = -1;
|
||||
si.StdOut = cp->PipeChildStd[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a pipe to sit between the children. */
|
||||
int p[2] = {-1,-1};
|
||||
if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
|
||||
{
|
||||
if (nextStdIn != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
kwsysProcessCreateInformation si = { -1, -1, -1, { -1, -1 } };
|
||||
int nextStdIn = cp->PipeChildStd[0];
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
/* Setup the process's pipes. */
|
||||
si.StdIn = nextStdIn;
|
||||
if (i == cp->NumberOfCommands - 1) {
|
||||
nextStdIn = -1;
|
||||
si.StdOut = cp->PipeChildStd[1];
|
||||
} else {
|
||||
/* Create a pipe to sit between the children. */
|
||||
int p[2] = { -1, -1 };
|
||||
if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) {
|
||||
if (nextStdIn != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
}
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
if (nextStdIn != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
/* Set close-on-exec flag on the pipe's ends. */
|
||||
if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
if (nextStdIn != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
}
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
nextStdIn = p[0];
|
||||
si.StdOut = p[1];
|
||||
nextStdIn = p[0];
|
||||
si.StdOut = p[1];
|
||||
}
|
||||
si.StdErr = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
|
||||
si.StdErr = cp->MergeOutput ? cp->PipeChildStd[1] : cp->PipeChildStd[2];
|
||||
|
||||
{
|
||||
int res = kwsysProcessCreate(cp, i, &si);
|
||||
{
|
||||
int res = kwsysProcessCreate(cp, i, &si);
|
||||
|
||||
/* Close our copies of pipes used between children. */
|
||||
if (si.StdIn != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&si.StdIn);
|
||||
}
|
||||
if (si.StdOut != cp->PipeChildStd[1])
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&si.StdOut);
|
||||
}
|
||||
if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput)
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&si.StdErr);
|
||||
}
|
||||
/* Close our copies of pipes used between children. */
|
||||
if (si.StdIn != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupDescriptor(&si.StdIn);
|
||||
}
|
||||
if (si.StdOut != cp->PipeChildStd[1]) {
|
||||
kwsysProcessCleanupDescriptor(&si.StdOut);
|
||||
}
|
||||
if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput) {
|
||||
kwsysProcessCleanupDescriptor(&si.StdErr);
|
||||
}
|
||||
|
||||
if(!res)
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
|
||||
if (nextStdIn != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
if (!res) {
|
||||
kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
|
||||
if (nextStdIn != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupDescriptor(&nextStdIn);
|
||||
}
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The parent process does not need the child's pipe ends. */
|
||||
for (i=0; i < 3; ++i)
|
||||
{
|
||||
for (i = 0; i < 3; ++i) {
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the working directory. */
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
if (cp->RealWorkingDirectory) {
|
||||
/* Some platforms specify that the chdir call may be
|
||||
interrupted. Repeat the call until it finishes. */
|
||||
while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
|
||||
while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
|
||||
;
|
||||
free(cp->RealWorkingDirectory);
|
||||
cp->RealWorkingDirectory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* All the pipes are now open. */
|
||||
cp->PipesLeft = KWSYSPE_PIPE_COUNT;
|
||||
@@ -1077,11 +994,10 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
||||
kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp)
|
||||
{
|
||||
/* Make sure a detached child process is running. */
|
||||
if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
|
||||
cp->TimeoutExpired || cp->Killed)
|
||||
{
|
||||
if (!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
|
||||
cp->TimeoutExpired || cp->Killed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close all the pipes safely. */
|
||||
kwsysProcessClosePipes(cp);
|
||||
@@ -1109,81 +1025,62 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
|
||||
int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
|
||||
double* userTimeout)
|
||||
{
|
||||
kwsysProcessTime userStartTime = {0, 0};
|
||||
kwsysProcessWaitData wd =
|
||||
{
|
||||
0,
|
||||
kwsysProcess_Pipe_None,
|
||||
0,
|
||||
0,
|
||||
{0, 0}
|
||||
};
|
||||
kwsysProcessTime userStartTime = { 0, 0 };
|
||||
kwsysProcessWaitData wd = { 0, kwsysProcess_Pipe_None, 0, 0, { 0, 0 } };
|
||||
wd.UserTimeout = userTimeout;
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
|
||||
cp->TimeoutExpired)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
|
||||
cp->TimeoutExpired) {
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the time at which user timeout period starts. */
|
||||
if(userTimeout)
|
||||
{
|
||||
if (userTimeout) {
|
||||
userStartTime = kwsysProcessTimeGetCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the time at which a timeout will expire, and whether it
|
||||
is the user or process timeout. */
|
||||
wd.User = kwsysProcessGetTimeoutTime(cp, userTimeout,
|
||||
&wd.TimeoutTime);
|
||||
wd.User = kwsysProcessGetTimeoutTime(cp, userTimeout, &wd.TimeoutTime);
|
||||
|
||||
/* Data can only be available when pipes are open. If the process
|
||||
is not running, cp->PipesLeft will be 0. */
|
||||
while(cp->PipesLeft > 0 &&
|
||||
!kwsysProcessWaitForPipe(cp, data, length, &wd)) {}
|
||||
while (cp->PipesLeft > 0 &&
|
||||
!kwsysProcessWaitForPipe(cp, data, length, &wd)) {
|
||||
}
|
||||
|
||||
/* Update the user timeout. */
|
||||
if(userTimeout)
|
||||
{
|
||||
if (userTimeout) {
|
||||
kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
|
||||
kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
|
||||
userStartTime);
|
||||
kwsysProcessTime difference =
|
||||
kwsysProcessTimeSubtract(userEndTime, userStartTime);
|
||||
double d = kwsysProcessTimeToDouble(difference);
|
||||
*userTimeout -= d;
|
||||
if(*userTimeout < 0)
|
||||
{
|
||||
if (*userTimeout < 0) {
|
||||
*userTimeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check what happened. */
|
||||
if(wd.PipeId)
|
||||
{
|
||||
if (wd.PipeId) {
|
||||
/* Data are ready on a pipe. */
|
||||
return wd.PipeId;
|
||||
}
|
||||
else if(wd.Expired)
|
||||
{
|
||||
} else if (wd.Expired) {
|
||||
/* A timeout has expired. */
|
||||
if(wd.User)
|
||||
{
|
||||
if (wd.User) {
|
||||
/* The user timeout has expired. It has no time left. */
|
||||
return kwsysProcess_Pipe_Timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The process timeout has expired. Kill the children now. */
|
||||
kwsysProcess_Kill(cp);
|
||||
cp->Killed = 0;
|
||||
cp->TimeoutExpired = 1;
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* No pipes are left open. */
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1202,11 +1099,9 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
|
||||
call to select. According to "man select_tut" we must deal
|
||||
with all descriptors reported by a call to select before
|
||||
passing them to another select call. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
if(cp->PipeReadEnds[i] >= 0 &&
|
||||
FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
if (cp->PipeReadEnds[i] >= 0 &&
|
||||
FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet)) {
|
||||
kwsysProcess_ssize_t n;
|
||||
|
||||
/* We are handling this pipe now. Remove it from the set. */
|
||||
@@ -1214,108 +1109,91 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
|
||||
|
||||
/* The pipe is ready to read without blocking. Keep trying to
|
||||
read until the operation is not interrupted. */
|
||||
while(((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && (errno == EINTR));
|
||||
if(n > 0)
|
||||
{
|
||||
while (((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE)) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
if (n > 0) {
|
||||
/* We have data on this pipe. */
|
||||
if(i == KWSYSPE_PIPE_SIGNAL)
|
||||
{
|
||||
if (i == KWSYSPE_PIPE_SIGNAL) {
|
||||
/* A child process has terminated. */
|
||||
kwsysProcessDestroy(cp);
|
||||
}
|
||||
else if(data && length)
|
||||
{
|
||||
} else if (data && length) {
|
||||
/* Report this data. */
|
||||
*data = cp->PipeBuffer;
|
||||
*length = (int)(n);
|
||||
switch(i)
|
||||
{
|
||||
switch (i) {
|
||||
case KWSYSPE_PIPE_STDOUT:
|
||||
wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
|
||||
wd->PipeId = kwsysProcess_Pipe_STDOUT;
|
||||
break;
|
||||
case KWSYSPE_PIPE_STDERR:
|
||||
wd->PipeId = kwsysProcess_Pipe_STDERR; break;
|
||||
};
|
||||
wd->PipeId = kwsysProcess_Pipe_STDERR;
|
||||
break;
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(n < 0 && errno == EAGAIN)
|
||||
{
|
||||
} else if (n < 0 && errno == EAGAIN) {
|
||||
/* No data are really ready. The select call lied. See the
|
||||
"man select" page on Linux for cases when this occurs. */
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* We are done reading from this pipe. */
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
||||
--cp->PipesLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have data, break early. */
|
||||
if(wd->PipeId)
|
||||
{
|
||||
if (wd->PipeId) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the set is empty (it should always be empty here
|
||||
anyway). */
|
||||
FD_ZERO(&cp->PipeSet);
|
||||
|
||||
/* Setup a timeout if required. */
|
||||
if(wd->TimeoutTime.tv_sec < 0)
|
||||
{
|
||||
if (wd->TimeoutTime.tv_sec < 0) {
|
||||
timeout = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
timeout = &timeoutLength;
|
||||
}
|
||||
if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime,
|
||||
wd->User?wd->UserTimeout:0,
|
||||
&timeoutLength, 0))
|
||||
{
|
||||
}
|
||||
if (kwsysProcessGetTimeoutLeft(
|
||||
&wd->TimeoutTime, wd->User ? wd->UserTimeout : 0, &timeoutLength, 0)) {
|
||||
/* Timeout has already expired. */
|
||||
wd->Expired = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the pipe reading ends that are still open. */
|
||||
max = -1;
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
if(cp->PipeReadEnds[i] >= 0)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
if (cp->PipeReadEnds[i] >= 0) {
|
||||
FD_SET(cp->PipeReadEnds[i], &cp->PipeSet);
|
||||
if(cp->PipeReadEnds[i] > max)
|
||||
{
|
||||
if (cp->PipeReadEnds[i] > max) {
|
||||
max = cp->PipeReadEnds[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have a non-empty set. */
|
||||
if(max < 0)
|
||||
{
|
||||
if (max < 0) {
|
||||
/* All pipes have closed. Child has terminated. */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run select to block until data are available. Repeat call
|
||||
until it is not interrupted. */
|
||||
while(((numReady = select(max+1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
|
||||
(errno == EINTR));
|
||||
while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
/* Check result of select. */
|
||||
if(numReady == 0)
|
||||
{
|
||||
if (numReady == 0) {
|
||||
/* Select's timeout expired. */
|
||||
wd->Expired = 1;
|
||||
return 1;
|
||||
}
|
||||
else if(numReady < 0)
|
||||
{
|
||||
} else if (numReady < 0) {
|
||||
/* Select returned an error. Leave the error description in the
|
||||
pipe buffer. */
|
||||
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
@@ -1324,98 +1202,84 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
|
||||
kwsysProcess_Kill(cp);
|
||||
cp->Killed = 0;
|
||||
cp->SelectError = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
/* Poll pipes for data since we do not have select. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
if(cp->PipeReadEnds[i] >= 0)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
if (cp->PipeReadEnds[i] >= 0) {
|
||||
const int fd = cp->PipeReadEnds[i];
|
||||
int n = read(fd, cp->PipeBuffer, KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
if(n > 0)
|
||||
{
|
||||
if (n > 0) {
|
||||
/* We have data on this pipe. */
|
||||
if(i == KWSYSPE_PIPE_SIGNAL)
|
||||
{
|
||||
if (i == KWSYSPE_PIPE_SIGNAL) {
|
||||
/* A child process has terminated. */
|
||||
kwsysProcessDestroy(cp);
|
||||
}
|
||||
else if(data && length)
|
||||
{
|
||||
} else if (data && length) {
|
||||
/* Report this data. */
|
||||
*data = cp->PipeBuffer;
|
||||
*length = n;
|
||||
switch(i)
|
||||
{
|
||||
switch (i) {
|
||||
case KWSYSPE_PIPE_STDOUT:
|
||||
wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
|
||||
wd->PipeId = kwsysProcess_Pipe_STDOUT;
|
||||
break;
|
||||
case KWSYSPE_PIPE_STDERR:
|
||||
wd->PipeId = kwsysProcess_Pipe_STDERR; break;
|
||||
};
|
||||
}
|
||||
wd->PipeId = kwsysProcess_Pipe_STDERR;
|
||||
break;
|
||||
};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (n == 0) /* EOF */
|
||||
{
|
||||
/* We are done reading from this pipe. */
|
||||
} else if (n == 0) /* EOF */
|
||||
{
|
||||
/* We are done reading from this pipe. */
|
||||
#if defined(__VMS)
|
||||
if(!cp->CommandsLeft)
|
||||
if (!cp->CommandsLeft)
|
||||
#endif
|
||||
{
|
||||
{
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
||||
--cp->PipesLeft;
|
||||
}
|
||||
}
|
||||
else if (n < 0) /* error */
|
||||
{
|
||||
} else if (n < 0) /* error */
|
||||
{
|
||||
#if defined(__VMS)
|
||||
if(!cp->CommandsLeft)
|
||||
{
|
||||
if (!cp->CommandsLeft) {
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
||||
--cp->PipesLeft;
|
||||
}
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
if((errno != EINTR) && (errno != EAGAIN))
|
||||
{
|
||||
strncpy(cp->ErrorMessage,strerror(errno),
|
||||
KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
if ((errno != EINTR) && (errno != EAGAIN)) {
|
||||
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
/* Kill the children now. */
|
||||
kwsysProcess_Kill(cp);
|
||||
cp->Killed = 0;
|
||||
cp->SelectError = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have data, break early. */
|
||||
if(wd->PipeId)
|
||||
{
|
||||
if (wd->PipeId) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime, wd->User?wd->UserTimeout:0,
|
||||
&timeoutLength, 1))
|
||||
{
|
||||
if (kwsysProcessGetTimeoutLeft(
|
||||
&wd->TimeoutTime, wd->User ? wd->UserTimeout : 0, &timeoutLength, 1)) {
|
||||
/* Timeout has already expired. */
|
||||
wd->Expired = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sleep a little, try again. */
|
||||
{
|
||||
unsigned int msec = ((timeoutLength.tv_sec * 1000) +
|
||||
(timeoutLength.tv_usec / 1000));
|
||||
if (msec > 100000)
|
||||
{
|
||||
msec = 100000; /* do not sleep more than 100 milliseconds at a time */
|
||||
unsigned int msec =
|
||||
((timeoutLength.tv_sec * 1000) + (timeoutLength.tv_usec / 1000));
|
||||
if (msec > 100000) {
|
||||
msec = 100000; /* do not sleep more than 100 milliseconds at a time */
|
||||
}
|
||||
kwsysProcess_usleep(msec);
|
||||
kwsysProcess_usleep(msec);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
@@ -1428,74 +1292,60 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
|
||||
int prPipe = 0;
|
||||
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for all the pipes to close. Ignore all data. */
|
||||
while((prPipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
|
||||
{
|
||||
if(prPipe == kwsysProcess_Pipe_Timeout)
|
||||
{
|
||||
while ((prPipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0) {
|
||||
if (prPipe == kwsysProcess_Pipe_Timeout) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there was an error in one of the waitpid calls. */
|
||||
if(cp->State == kwsysProcess_State_Error)
|
||||
{
|
||||
if (cp->State == kwsysProcess_State_Error) {
|
||||
/* The error message is already in its buffer. Tell
|
||||
kwsysProcessCleanup to not create it. */
|
||||
kwsysProcessCleanup(cp, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the child reported an error invoking the process. */
|
||||
if(cp->SelectError)
|
||||
{
|
||||
if (cp->SelectError) {
|
||||
/* The error message is already in its buffer. Tell
|
||||
kwsysProcessCleanup to not create it. */
|
||||
kwsysProcessCleanup(cp, 0);
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the status of the last process in the pipeline. */
|
||||
status = cp->CommandExitCodes[cp->NumberOfCommands-1];
|
||||
status = cp->CommandExitCodes[cp->NumberOfCommands - 1];
|
||||
|
||||
/* Determine the outcome. */
|
||||
if(cp->Killed)
|
||||
{
|
||||
if (cp->Killed) {
|
||||
/* We killed the child. */
|
||||
cp->State = kwsysProcess_State_Killed;
|
||||
}
|
||||
else if(cp->TimeoutExpired)
|
||||
{
|
||||
} else if (cp->TimeoutExpired) {
|
||||
/* The timeout expired. */
|
||||
cp->State = kwsysProcess_State_Expired;
|
||||
}
|
||||
else if(WIFEXITED(status))
|
||||
{
|
||||
} else if (WIFEXITED(status)) {
|
||||
/* The child exited normally. */
|
||||
cp->State = kwsysProcess_State_Exited;
|
||||
cp->ExitException = kwsysProcess_Exception_None;
|
||||
cp->ExitCode = status;
|
||||
cp->ExitValue = (int)WEXITSTATUS(status);
|
||||
}
|
||||
else if(WIFSIGNALED(status))
|
||||
{
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
/* The child received an unhandled signal. */
|
||||
cp->State = kwsysProcess_State_Exception;
|
||||
cp->ExitCode = status;
|
||||
kwsysProcessSetExitException(cp, (int)WTERMSIG(status));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Error getting the child return code. */
|
||||
strcpy(cp->ErrorMessage, "Error getting child return code.");
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normal cleanup. */
|
||||
kwsysProcessCleanup(cp, 0);
|
||||
@@ -1507,38 +1357,31 @@ void kwsysProcess_Interrupt(kwsysProcess* cp)
|
||||
{
|
||||
int i;
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Interrupt the children. */
|
||||
if (cp->CreateProcessGroup)
|
||||
{
|
||||
if(cp->ForkPIDs)
|
||||
{
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
if (cp->CreateProcessGroup) {
|
||||
if (cp->ForkPIDs) {
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
/* Make sure the PID is still valid. */
|
||||
if(cp->ForkPIDs[i])
|
||||
{
|
||||
if (cp->ForkPIDs[i]) {
|
||||
/* The user created a process group for this process. The group ID
|
||||
is the process ID for the original process in the group. */
|
||||
kill(-cp->ForkPIDs[i], SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* No process group was created. Kill our own process group.
|
||||
NOTE: While one could argue that we could call kill(cp->ForkPIDs[i],
|
||||
SIGINT) as a way to still interrupt the process even though it's not in
|
||||
a special group, this is not an option on Windows. Therefore, we kill
|
||||
the current process group for consistency with Windows. */
|
||||
kill(0, SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1547,10 +1390,9 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* First close the child exit report pipe write end to avoid causing a
|
||||
SIGPIPE when the child terminates and our signal handler tries to
|
||||
@@ -1566,19 +1408,18 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
||||
|
||||
/* Kill the children. */
|
||||
cp->Killed = 1;
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
int status;
|
||||
if(cp->ForkPIDs[i])
|
||||
{
|
||||
if (cp->ForkPIDs[i]) {
|
||||
/* Kill the child. */
|
||||
kwsysProcessKill(cp->ForkPIDs[i]);
|
||||
|
||||
/* Reap the child. Keep trying until the call is not
|
||||
interrupted. */
|
||||
while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR));
|
||||
}
|
||||
while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Close all the pipe read ends. Do this after killing the
|
||||
@@ -1595,15 +1436,15 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
||||
compiler warnings. */
|
||||
static void kwsysProcessVolatileFree(volatile void* p)
|
||||
{
|
||||
/* clang has made it impossible to free memory that points to volatile
|
||||
without first using special pragmas to disable a warning... */
|
||||
/* clang has made it impossible to free memory that points to volatile
|
||||
without first using special pragmas to disable a warning... */
|
||||
#if defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-qual"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
free((void*)p); /* The cast will silence most compilers, but not clang. */
|
||||
#if defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
# pragma clang diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1613,14 +1454,12 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
|
||||
{
|
||||
int i;
|
||||
volatile pid_t* oldForkPIDs;
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
cp->PipeReadEnds[i] = -1;
|
||||
}
|
||||
for(i=0; i < 3; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
cp->PipeChildStd[i] = -1;
|
||||
}
|
||||
}
|
||||
cp->SignalPipe = -1;
|
||||
cp->SelectError = 0;
|
||||
cp->StartTime.tv_sec = -1;
|
||||
@@ -1642,36 +1481,31 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
|
||||
strcpy(cp->ExitExceptionString, "No exception");
|
||||
|
||||
oldForkPIDs = cp->ForkPIDs;
|
||||
cp->ForkPIDs = (volatile pid_t*)malloc(
|
||||
sizeof(volatile pid_t)*(size_t)(cp->NumberOfCommands));
|
||||
if(oldForkPIDs)
|
||||
{
|
||||
cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) *
|
||||
(size_t)(cp->NumberOfCommands));
|
||||
if (oldForkPIDs) {
|
||||
kwsysProcessVolatileFree(oldForkPIDs);
|
||||
}
|
||||
if(!cp->ForkPIDs)
|
||||
{
|
||||
}
|
||||
if (!cp->ForkPIDs) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
|
||||
}
|
||||
}
|
||||
|
||||
if(cp->CommandExitCodes)
|
||||
{
|
||||
if (cp->CommandExitCodes) {
|
||||
free(cp->CommandExitCodes);
|
||||
}
|
||||
cp->CommandExitCodes = (int*)malloc(sizeof(int)*
|
||||
(size_t)(cp->NumberOfCommands));
|
||||
if(!cp->CommandExitCodes)
|
||||
{
|
||||
}
|
||||
cp->CommandExitCodes =
|
||||
(int*)malloc(sizeof(int) * (size_t)(cp->NumberOfCommands));
|
||||
if (!cp->CommandExitCodes) {
|
||||
return 0;
|
||||
}
|
||||
memset(cp->CommandExitCodes, 0, sizeof(int)*(size_t)(cp->NumberOfCommands));
|
||||
}
|
||||
memset(cp->CommandExitCodes, 0,
|
||||
sizeof(int) * (size_t)(cp->NumberOfCommands));
|
||||
|
||||
/* Allocate memory to save the real working directory. */
|
||||
if ( cp->WorkingDirectory )
|
||||
{
|
||||
if (cp->WorkingDirectory) {
|
||||
#if defined(MAXPATHLEN)
|
||||
cp->RealWorkingDirectoryLength = MAXPATHLEN;
|
||||
#elif defined(PATH_MAX)
|
||||
@@ -1681,11 +1515,10 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
|
||||
#endif
|
||||
cp->RealWorkingDirectory =
|
||||
(char*)malloc((size_t)(cp->RealWorkingDirectoryLength));
|
||||
if(!cp->RealWorkingDirectory)
|
||||
{
|
||||
if (!cp->RealWorkingDirectory) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1697,86 +1530,77 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(error)
|
||||
{
|
||||
if (error) {
|
||||
/* We are cleaning up due to an error. Report the error message
|
||||
if one has not been provided already. */
|
||||
if(cp->ErrorMessage[0] == 0)
|
||||
{
|
||||
if (cp->ErrorMessage[0] == 0) {
|
||||
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the error state. */
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
|
||||
/* Kill any children already started. */
|
||||
if(cp->ForkPIDs)
|
||||
{
|
||||
if (cp->ForkPIDs) {
|
||||
int status;
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
if(cp->ForkPIDs[i])
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
if (cp->ForkPIDs[i]) {
|
||||
/* Kill the child. */
|
||||
kwsysProcessKill(cp->ForkPIDs[i]);
|
||||
|
||||
/* Reap the child. Keep trying until the call is not
|
||||
interrupted. */
|
||||
while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
|
||||
(errno == EINTR));
|
||||
}
|
||||
while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the working directory. */
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
|
||||
}
|
||||
if (cp->RealWorkingDirectory) {
|
||||
while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not creating a detached child, remove this object from the
|
||||
global set of process objects that wish to be notified when a
|
||||
child exits. */
|
||||
if(!cp->OptionDetach)
|
||||
{
|
||||
if (!cp->OptionDetach) {
|
||||
kwsysProcessesRemove(cp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
if(cp->ForkPIDs)
|
||||
{
|
||||
if (cp->ForkPIDs) {
|
||||
kwsysProcessVolatileFree(cp->ForkPIDs);
|
||||
cp->ForkPIDs = 0;
|
||||
}
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
}
|
||||
if (cp->RealWorkingDirectory) {
|
||||
free(cp->RealWorkingDirectory);
|
||||
cp->RealWorkingDirectory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close pipe handles. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
||||
}
|
||||
for(i=0; i < 3; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Close the given file descriptor if it is open. Reset its value to -1. */
|
||||
static void kwsysProcessCleanupDescriptor(int* pfd)
|
||||
{
|
||||
if(pfd && *pfd > 2)
|
||||
{
|
||||
if (pfd && *pfd > 2) {
|
||||
/* Keep trying to close until it is not interrupted by a
|
||||
* signal. */
|
||||
while((close(*pfd) < 0) && (errno == EINTR));
|
||||
while ((close(*pfd) < 0) && (errno == EINTR))
|
||||
;
|
||||
*pfd = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1785,42 +1609,40 @@ static void kwsysProcessClosePipes(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Close any pipes that are still open. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
if(cp->PipeReadEnds[i] >= 0)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
if (cp->PipeReadEnds[i] >= 0) {
|
||||
#if KWSYSPE_USE_SELECT
|
||||
/* If the pipe was reported by the last call to select, we must
|
||||
read from it. This is needed to satisfy the suggestions from
|
||||
"man select_tut" and is not needed for the polling
|
||||
implementation. Ignore the data. */
|
||||
if(FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
|
||||
{
|
||||
if (FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet)) {
|
||||
/* We are handling this pipe now. Remove it from the set. */
|
||||
FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
|
||||
|
||||
/* The pipe is ready to read without blocking. Keep trying to
|
||||
read until the operation is not interrupted. */
|
||||
while((read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE) < 0) && (errno == EINTR));
|
||||
}
|
||||
while ((read(cp->PipeReadEnds[i], cp->PipeBuffer,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We are done reading from this pipe. */
|
||||
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
|
||||
--cp->PipesLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcessSetNonBlocking(int fd)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
if(flags >= 0)
|
||||
{
|
||||
if (flags >= 0) {
|
||||
flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
return flags >= 0;
|
||||
}
|
||||
|
||||
@@ -1839,30 +1661,27 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
ssize_t readRes;
|
||||
|
||||
/* Create the error reporting pipe. */
|
||||
if(pipe(si->ErrorPipe) < 0)
|
||||
{
|
||||
if (pipe(si->ErrorPipe) < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a pipe for detecting that the child process has created a process
|
||||
group and session. */
|
||||
if(pipe(pgidPipe) < 0)
|
||||
{
|
||||
if (pipe(pgidPipe) < 0) {
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag on the pipe's write end. */
|
||||
if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
|
||||
fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0)
|
||||
{
|
||||
if (fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
|
||||
fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0) {
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Block SIGINT / SIGTERM while we start. The purpose is so that our signal
|
||||
handler doesn't get called from the child process after the fork and
|
||||
@@ -1870,16 +1689,15 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
|
||||
{
|
||||
if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) {
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fork off a child process. */
|
||||
/* Fork off a child process. */
|
||||
#if defined(__VMS)
|
||||
/* VMS needs vfork and execvp to be in the same function because
|
||||
they use setjmp/longjmp to run the child startup code in the
|
||||
@@ -1889,18 +1707,16 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
#else
|
||||
cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
|
||||
#endif
|
||||
if(cp->ForkPIDs[prIndex] < 0)
|
||||
{
|
||||
if (cp->ForkPIDs[prIndex] < 0) {
|
||||
sigprocmask(SIG_SETMASK, &old_mask, 0);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(cp->ForkPIDs[prIndex] == 0)
|
||||
{
|
||||
if (cp->ForkPIDs[prIndex] == 0) {
|
||||
#if defined(__VMS)
|
||||
/* Specify standard pipes for child process. */
|
||||
decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
|
||||
@@ -1911,22 +1727,17 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
close(pgidPipe[0]);
|
||||
|
||||
/* Setup the stdin, stdout, and stderr pipes. */
|
||||
if(si->StdIn > 0)
|
||||
{
|
||||
if (si->StdIn > 0) {
|
||||
dup2(si->StdIn, 0);
|
||||
}
|
||||
else if(si->StdIn < 0)
|
||||
{
|
||||
} else if (si->StdIn < 0) {
|
||||
close(0);
|
||||
}
|
||||
if(si->StdOut != 1)
|
||||
{
|
||||
}
|
||||
if (si->StdOut != 1) {
|
||||
dup2(si->StdOut, 1);
|
||||
}
|
||||
if(si->StdErr != 2)
|
||||
{
|
||||
}
|
||||
if (si->StdErr != 2) {
|
||||
dup2(si->StdErr, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the close-on-exec flag for stdin, stdout, and stderr.
|
||||
All other pipe handles will be closed when exec succeeds. */
|
||||
@@ -1945,10 +1756,9 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
the child getting hung up on signals like SIGTTOU. (In the real world,
|
||||
this has been observed where "git svn" ends up calling the "resize"
|
||||
program which opens /dev/tty. */
|
||||
if(cp->CreateProcessGroup && setsid() < 0)
|
||||
{
|
||||
if (cp->CreateProcessGroup && setsid() < 0) {
|
||||
kwsysProcessChildErrorExit(si->ErrorPipe[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Execute the real process. If successful, this does not return. */
|
||||
@@ -1958,7 +1768,7 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
|
||||
/* Failure. Report error to parent and terminate. */
|
||||
kwsysProcessChildErrorExit(si->ErrorPipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__VMS)
|
||||
/* Restore the standard pipes of this process. */
|
||||
@@ -1973,22 +1783,21 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
/* Make sure the child is in the process group before we proceed. This
|
||||
avoids race conditions with calls to the kill function that we make for
|
||||
signalling process groups. */
|
||||
while((readRes = read(pgidPipe[0], &tmp, 1)) > 0);
|
||||
if(readRes < 0)
|
||||
{
|
||||
while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0)
|
||||
;
|
||||
if (readRes < 0) {
|
||||
sigprocmask(SIG_SETMASK, &old_mask, 0);
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
kwsysProcessCleanupDescriptor(&pgidPipe[0]);
|
||||
|
||||
/* Unmask signals. */
|
||||
if(sigprocmask(SIG_SETMASK, &old_mask, 0) < 0)
|
||||
{
|
||||
if (sigprocmask(SIG_SETMASK, &old_mask, 0) < 0) {
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* A child has been created. */
|
||||
++cp->CommandsLeft;
|
||||
@@ -1996,28 +1805,26 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
|
||||
/* Block until the child's exec call succeeds and closes the error
|
||||
pipe or writes data to the pipe to report an error. */
|
||||
{
|
||||
kwsysProcess_ssize_t total = 0;
|
||||
kwsysProcess_ssize_t n = 1;
|
||||
/* Read the entire error message up to the length of our buffer. */
|
||||
while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
|
||||
{
|
||||
/* Keep trying to read until the operation is not interrupted. */
|
||||
while(((n = read(si->ErrorPipe[0], cp->ErrorMessage+total,
|
||||
(size_t)(KWSYSPE_PIPE_BUFFER_SIZE-total))) < 0) &&
|
||||
(errno == EINTR));
|
||||
if(n > 0)
|
||||
{
|
||||
total += n;
|
||||
kwsysProcess_ssize_t total = 0;
|
||||
kwsysProcess_ssize_t n = 1;
|
||||
/* Read the entire error message up to the length of our buffer. */
|
||||
while (total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0) {
|
||||
/* Keep trying to read until the operation is not interrupted. */
|
||||
while (((n = read(si->ErrorPipe[0], cp->ErrorMessage + total,
|
||||
(size_t)(KWSYSPE_PIPE_BUFFER_SIZE - total))) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
if (n > 0) {
|
||||
total += n;
|
||||
}
|
||||
}
|
||||
|
||||
/* We are done with the error reporting pipe read end. */
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
/* We are done with the error reporting pipe read end. */
|
||||
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
|
||||
|
||||
if(total > 0)
|
||||
{
|
||||
/* The child failed to execute the process. */
|
||||
return 0;
|
||||
if (total > 0) {
|
||||
/* The child failed to execute the process. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2036,25 +1843,21 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
|
||||
{
|
||||
if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
if(cp->ForkPIDs[i])
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
if (cp->ForkPIDs[i]) {
|
||||
int result;
|
||||
while(((result = waitpid(cp->ForkPIDs[i],
|
||||
&cp->CommandExitCodes[i], WNOHANG)) < 0) &&
|
||||
(errno == EINTR));
|
||||
if(result > 0)
|
||||
{
|
||||
while (((result = waitpid(cp->ForkPIDs[i], &cp->CommandExitCodes[i],
|
||||
WNOHANG)) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
if (result > 0) {
|
||||
/* This child has termianted. */
|
||||
cp->ForkPIDs[i] = 0;
|
||||
if(--cp->CommandsLeft == 0)
|
||||
{
|
||||
if (--cp->CommandsLeft == 0) {
|
||||
/* All children have terminated. Close the signal pipe
|
||||
write end so that no more notifications are sent to this
|
||||
object. */
|
||||
@@ -2064,16 +1867,14 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
|
||||
WaitForData to use a non-blocking read to get the
|
||||
rest of the data from the pipe. This is needed when
|
||||
grandchildren keep the output pipes open. */
|
||||
}
|
||||
}
|
||||
else if(result < 0 && cp->State != kwsysProcess_State_Error)
|
||||
{
|
||||
} else if (result < 0 && cp->State != kwsysProcess_State_Error) {
|
||||
/* Unexpected error. Report the first time this happens. */
|
||||
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable signals. */
|
||||
sigprocmask(SIG_SETMASK, &old_mask, 0);
|
||||
@@ -2083,25 +1884,22 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
|
||||
static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
|
||||
{
|
||||
int fout;
|
||||
if(!name)
|
||||
{
|
||||
if (!name) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the existing descriptor. */
|
||||
kwsysProcessCleanupDescriptor(p);
|
||||
|
||||
/* Open a file for the pipe to write. */
|
||||
if((fout = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
|
||||
{
|
||||
if ((fout = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag on the pipe's end. */
|
||||
if(fcntl(fout, F_SETFD, FD_CLOEXEC) < 0)
|
||||
{
|
||||
if (fcntl(fout, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign the replacement descriptor. */
|
||||
*p = fout;
|
||||
@@ -2117,11 +1915,10 @@ static int kwsysProcessSetupOutputPipeNative(int* p, int des[2])
|
||||
/* Set close-on-exec flag on the pipe's ends. The proper end will
|
||||
be dup2-ed into the standard descriptor number after fork but
|
||||
before exec. */
|
||||
if((fcntl(des[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(des[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
if ((fcntl(des[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(des[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign the replacement descriptor. */
|
||||
*p = des[1];
|
||||
@@ -2136,29 +1933,27 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
|
||||
{
|
||||
/* The first time this is called, we need to calculate the time at
|
||||
which the child will timeout. */
|
||||
if(cp->Timeout > 0 && cp->TimeoutTime.tv_sec < 0)
|
||||
{
|
||||
if (cp->Timeout > 0 && cp->TimeoutTime.tv_sec < 0) {
|
||||
kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
|
||||
cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start with process timeout. */
|
||||
*timeoutTime = cp->TimeoutTime;
|
||||
|
||||
/* Check if the user timeout is earlier. */
|
||||
if(userTimeout)
|
||||
{
|
||||
if (userTimeout) {
|
||||
kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
|
||||
kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
|
||||
kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
|
||||
userTimeoutLength);
|
||||
if(timeoutTime->tv_sec < 0 ||
|
||||
kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
|
||||
{
|
||||
kwsysProcessTime userTimeoutLength =
|
||||
kwsysProcessTimeFromDouble(*userTimeout);
|
||||
kwsysProcessTime userTimeoutTime =
|
||||
kwsysProcessTimeAdd(currentTime, userTimeoutLength);
|
||||
if (timeoutTime->tv_sec < 0 ||
|
||||
kwsysProcessTimeLess(userTimeoutTime, *timeoutTime)) {
|
||||
*timeoutTime = userTimeoutTime;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2170,38 +1965,31 @@ static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
|
||||
kwsysProcessTimeNative* timeoutLength,
|
||||
int zeroIsExpired)
|
||||
{
|
||||
if(timeoutTime->tv_sec < 0)
|
||||
{
|
||||
if (timeoutTime->tv_sec < 0) {
|
||||
/* No timeout time has been requested. */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Calculate the remaining time. */
|
||||
kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
|
||||
kwsysProcessTime timeLeft = kwsysProcessTimeSubtract(*timeoutTime,
|
||||
currentTime);
|
||||
if(timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0)
|
||||
{
|
||||
kwsysProcessTime timeLeft =
|
||||
kwsysProcessTimeSubtract(*timeoutTime, currentTime);
|
||||
if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
|
||||
/* Caller has explicitly requested a zero timeout. */
|
||||
timeLeft.tv_sec = 0;
|
||||
timeLeft.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(timeLeft.tv_sec < 0 ||
|
||||
(timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired))
|
||||
{
|
||||
if (timeLeft.tv_sec < 0 ||
|
||||
(timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
|
||||
/* Timeout has already expired. */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* There is some time left. */
|
||||
timeoutLength->tv_sec = timeLeft.tv_sec;
|
||||
timeoutLength->tv_usec = timeLeft.tv_usec;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2218,7 +2006,7 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static double kwsysProcessTimeToDouble(kwsysProcessTime t)
|
||||
{
|
||||
return (double)t.tv_sec + (double)(t.tv_usec)*0.000001;
|
||||
return (double)t.tv_sec + (double)(t.tv_usec) * 0.000001;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2226,7 +2014,7 @@ static kwsysProcessTime kwsysProcessTimeFromDouble(double d)
|
||||
{
|
||||
kwsysProcessTime t;
|
||||
t.tv_sec = (long)d;
|
||||
t.tv_usec = (long)((d-(double)(t.tv_sec))*1000000);
|
||||
t.tv_usec = (long)((d - (double)(t.tv_sec)) * 1000000);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -2238,158 +2026,227 @@ static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2)
|
||||
{
|
||||
kwsysProcessTime out;
|
||||
out.tv_sec = in1.tv_sec + in2.tv_sec;
|
||||
out.tv_usec = in1.tv_usec + in2.tv_usec;
|
||||
if(out.tv_usec >= 1000000)
|
||||
{
|
||||
if (out.tv_usec >= 1000000) {
|
||||
out.tv_usec -= 1000000;
|
||||
out.tv_sec += 1;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2)
|
||||
{
|
||||
kwsysProcessTime out;
|
||||
out.tv_sec = in1.tv_sec - in2.tv_sec;
|
||||
out.tv_usec = in1.tv_usec - in2.tv_usec;
|
||||
if(out.tv_usec < 0)
|
||||
{
|
||||
if (out.tv_usec < 0) {
|
||||
out.tv_usec += 1000000;
|
||||
out.tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define KWSYSPE_CASE(type, str) \
|
||||
cp->ExitException = kwsysProcess_Exception_##type; \
|
||||
#define KWSYSPE_CASE(type, str) \
|
||||
cp->ExitException = kwsysProcess_Exception_##type; \
|
||||
strcpy(cp->ExitExceptionString, str)
|
||||
static void kwsysProcessSetExitException(kwsysProcess* cp, int sig)
|
||||
{
|
||||
switch (sig)
|
||||
{
|
||||
switch (sig) {
|
||||
#ifdef SIGSEGV
|
||||
case SIGSEGV: KWSYSPE_CASE(Fault, "Segmentation fault"); break;
|
||||
case SIGSEGV:
|
||||
KWSYSPE_CASE(Fault, "Segmentation fault");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
# if !defined(SIGSEGV) || SIGBUS != SIGSEGV
|
||||
case SIGBUS: KWSYSPE_CASE(Fault, "Bus error"); break;
|
||||
# endif
|
||||
#if !defined(SIGSEGV) || SIGBUS != SIGSEGV
|
||||
case SIGBUS:
|
||||
KWSYSPE_CASE(Fault, "Bus error");
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SIGFPE
|
||||
case SIGFPE: KWSYSPE_CASE(Numerical, "Floating-point exception"); break;
|
||||
case SIGFPE:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGILL
|
||||
case SIGILL: KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
|
||||
case SIGILL:
|
||||
KWSYSPE_CASE(Illegal, "Illegal instruction");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGINT
|
||||
case SIGINT: KWSYSPE_CASE(Interrupt, "User interrupt"); break;
|
||||
case SIGINT:
|
||||
KWSYSPE_CASE(Interrupt, "User interrupt");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
case SIGABRT: KWSYSPE_CASE(Other, "Child aborted"); break;
|
||||
case SIGABRT:
|
||||
KWSYSPE_CASE(Other, "Child aborted");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGKILL
|
||||
case SIGKILL: KWSYSPE_CASE(Other, "Child killed"); break;
|
||||
case SIGKILL:
|
||||
KWSYSPE_CASE(Other, "Child killed");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
case SIGTERM: KWSYSPE_CASE(Other, "Child terminated"); break;
|
||||
case SIGTERM:
|
||||
KWSYSPE_CASE(Other, "Child terminated");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
case SIGHUP: KWSYSPE_CASE(Other, "SIGHUP"); break;
|
||||
case SIGHUP:
|
||||
KWSYSPE_CASE(Other, "SIGHUP");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
case SIGQUIT: KWSYSPE_CASE(Other, "SIGQUIT"); break;
|
||||
case SIGQUIT:
|
||||
KWSYSPE_CASE(Other, "SIGQUIT");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGTRAP
|
||||
case SIGTRAP: KWSYSPE_CASE(Other, "SIGTRAP"); break;
|
||||
case SIGTRAP:
|
||||
KWSYSPE_CASE(Other, "SIGTRAP");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
# if !defined(SIGABRT) || SIGIOT != SIGABRT
|
||||
case SIGIOT: KWSYSPE_CASE(Other, "SIGIOT"); break;
|
||||
# endif
|
||||
#if !defined(SIGABRT) || SIGIOT != SIGABRT
|
||||
case SIGIOT:
|
||||
KWSYSPE_CASE(Other, "SIGIOT");
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
case SIGUSR1: KWSYSPE_CASE(Other, "SIGUSR1"); break;
|
||||
case SIGUSR1:
|
||||
KWSYSPE_CASE(Other, "SIGUSR1");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGUSR2
|
||||
case SIGUSR2: KWSYSPE_CASE(Other, "SIGUSR2"); break;
|
||||
case SIGUSR2:
|
||||
KWSYSPE_CASE(Other, "SIGUSR2");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
case SIGPIPE: KWSYSPE_CASE(Other, "SIGPIPE"); break;
|
||||
case SIGPIPE:
|
||||
KWSYSPE_CASE(Other, "SIGPIPE");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGALRM
|
||||
case SIGALRM: KWSYSPE_CASE(Other, "SIGALRM"); break;
|
||||
case SIGALRM:
|
||||
KWSYSPE_CASE(Other, "SIGALRM");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGSTKFLT
|
||||
case SIGSTKFLT: KWSYSPE_CASE(Other, "SIGSTKFLT"); break;
|
||||
case SIGSTKFLT:
|
||||
KWSYSPE_CASE(Other, "SIGSTKFLT");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
case SIGCHLD: KWSYSPE_CASE(Other, "SIGCHLD"); break;
|
||||
case SIGCHLD:
|
||||
KWSYSPE_CASE(Other, "SIGCHLD");
|
||||
break;
|
||||
#elif defined(SIGCLD)
|
||||
case SIGCLD: KWSYSPE_CASE(Other, "SIGCLD"); break;
|
||||
case SIGCLD:
|
||||
KWSYSPE_CASE(Other, "SIGCLD");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGCONT
|
||||
case SIGCONT: KWSYSPE_CASE(Other, "SIGCONT"); break;
|
||||
case SIGCONT:
|
||||
KWSYSPE_CASE(Other, "SIGCONT");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGSTOP
|
||||
case SIGSTOP: KWSYSPE_CASE(Other, "SIGSTOP"); break;
|
||||
case SIGSTOP:
|
||||
KWSYSPE_CASE(Other, "SIGSTOP");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
case SIGTSTP: KWSYSPE_CASE(Other, "SIGTSTP"); break;
|
||||
case SIGTSTP:
|
||||
KWSYSPE_CASE(Other, "SIGTSTP");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
case SIGTTIN: KWSYSPE_CASE(Other, "SIGTTIN"); break;
|
||||
case SIGTTIN:
|
||||
KWSYSPE_CASE(Other, "SIGTTIN");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
case SIGTTOU: KWSYSPE_CASE(Other, "SIGTTOU"); break;
|
||||
case SIGTTOU:
|
||||
KWSYSPE_CASE(Other, "SIGTTOU");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGURG
|
||||
case SIGURG: KWSYSPE_CASE(Other, "SIGURG"); break;
|
||||
case SIGURG:
|
||||
KWSYSPE_CASE(Other, "SIGURG");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
case SIGXCPU: KWSYSPE_CASE(Other, "SIGXCPU"); break;
|
||||
case SIGXCPU:
|
||||
KWSYSPE_CASE(Other, "SIGXCPU");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
case SIGXFSZ: KWSYSPE_CASE(Other, "SIGXFSZ"); break;
|
||||
case SIGXFSZ:
|
||||
KWSYSPE_CASE(Other, "SIGXFSZ");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
case SIGVTALRM: KWSYSPE_CASE(Other, "SIGVTALRM"); break;
|
||||
case SIGVTALRM:
|
||||
KWSYSPE_CASE(Other, "SIGVTALRM");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
case SIGPROF: KWSYSPE_CASE(Other, "SIGPROF"); break;
|
||||
case SIGPROF:
|
||||
KWSYSPE_CASE(Other, "SIGPROF");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
case SIGWINCH: KWSYSPE_CASE(Other, "SIGWINCH"); break;
|
||||
case SIGWINCH:
|
||||
KWSYSPE_CASE(Other, "SIGWINCH");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGPOLL
|
||||
case SIGPOLL: KWSYSPE_CASE(Other, "SIGPOLL"); break;
|
||||
case SIGPOLL:
|
||||
KWSYSPE_CASE(Other, "SIGPOLL");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGIO
|
||||
# if !defined(SIGPOLL) || SIGIO != SIGPOLL
|
||||
case SIGIO: KWSYSPE_CASE(Other, "SIGIO"); break;
|
||||
# endif
|
||||
#if !defined(SIGPOLL) || SIGIO != SIGPOLL
|
||||
case SIGIO:
|
||||
KWSYSPE_CASE(Other, "SIGIO");
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
case SIGPWR: KWSYSPE_CASE(Other, "SIGPWR"); break;
|
||||
case SIGPWR:
|
||||
KWSYSPE_CASE(Other, "SIGPWR");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
case SIGSYS: KWSYSPE_CASE(Other, "SIGSYS"); break;
|
||||
case SIGSYS:
|
||||
KWSYSPE_CASE(Other, "SIGSYS");
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGUNUSED
|
||||
# if !defined(SIGSYS) || SIGUNUSED != SIGSYS
|
||||
case SIGUNUSED: KWSYSPE_CASE(Other, "SIGUNUSED"); break;
|
||||
# endif
|
||||
#if !defined(SIGSYS) || SIGUNUSED != SIGSYS
|
||||
case SIGUNUSED:
|
||||
KWSYSPE_CASE(Other, "SIGUNUSED");
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
cp->ExitException = kwsysProcess_Exception_Other;
|
||||
sprintf(cp->ExitExceptionString, "Signal %d", sig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef KWSYSPE_CASE
|
||||
|
||||
@@ -2405,7 +2262,7 @@ static void kwsysProcessChildErrorExit(int errorPipe)
|
||||
strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
|
||||
|
||||
/* Report the error to the parent through the special pipe. */
|
||||
result=write(errorPipe, buffer, strlen(buffer));
|
||||
result = write(errorPipe, buffer, strlen(buffer));
|
||||
(void)result;
|
||||
|
||||
/* Terminate without cleanup. */
|
||||
@@ -2532,55 +2389,47 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
|
||||
kwsysProcessCreateInformation* si)
|
||||
{
|
||||
/* Create a detached process if requested. */
|
||||
if(cp->OptionDetach)
|
||||
{
|
||||
if (cp->OptionDetach) {
|
||||
/* Create an intermediate process. */
|
||||
pid_t middle_pid = fork();
|
||||
if(middle_pid < 0)
|
||||
{
|
||||
if (middle_pid < 0) {
|
||||
/* Fork failed. Return as if we were not detaching. */
|
||||
return middle_pid;
|
||||
}
|
||||
else if(middle_pid == 0)
|
||||
{
|
||||
} else if (middle_pid == 0) {
|
||||
/* This is the intermediate process. Create the real child. */
|
||||
pid_t child_pid = fork();
|
||||
if(child_pid == 0)
|
||||
{
|
||||
if (child_pid == 0) {
|
||||
/* This is the real child process. There is nothing to do here. */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Use the error pipe to report the pid to the real parent. */
|
||||
while((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
|
||||
(errno == EINTR));
|
||||
while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
/* Exit without cleanup. The parent holds all resources. */
|
||||
kwsysProcessExit();
|
||||
return 0; /* Never reached, but avoids SunCC warning. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* This is the original parent process. The intermediate
|
||||
process will use the error pipe to report the pid of the
|
||||
detached child. */
|
||||
pid_t child_pid;
|
||||
int status;
|
||||
while((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
|
||||
(errno == EINTR));
|
||||
while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
/* Wait for the intermediate process to exit and clean it up. */
|
||||
while((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR));
|
||||
while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR))
|
||||
;
|
||||
return child_pid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Not creating a detached process. Use normal fork. */
|
||||
return fork();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2589,23 +2438,23 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
|
||||
Here we define the command to call on each platform and the
|
||||
corresponding parsing format string. The parsing format should
|
||||
have two integers to store: the pid and then the ppid. */
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) \
|
||||
|| defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__)
|
||||
# define KWSYSPE_PS_COMMAND "ps axo pid,ppid"
|
||||
# define KWSYSPE_PS_FORMAT "%d %d\n"
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__)
|
||||
#define KWSYSPE_PS_COMMAND "ps axo pid,ppid"
|
||||
#define KWSYSPE_PS_FORMAT "%d %d\n"
|
||||
#elif defined(__sun) && (defined(__SVR4) || defined(__svr4__)) /* Solaris */
|
||||
# define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid"
|
||||
# define KWSYSPE_PS_FORMAT "%d %d\n"
|
||||
#elif defined(__hpux) || defined(__sun__) || defined(__sgi) || defined(_AIX) \
|
||||
|| defined(__sparc)
|
||||
# define KWSYSPE_PS_COMMAND "ps -ef"
|
||||
# define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n"
|
||||
#define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid"
|
||||
#define KWSYSPE_PS_FORMAT "%d %d\n"
|
||||
#elif defined(__hpux) || defined(__sun__) || defined(__sgi) || \
|
||||
defined(_AIX) || defined(__sparc)
|
||||
#define KWSYSPE_PS_COMMAND "ps -ef"
|
||||
#define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n"
|
||||
#elif defined(__QNX__)
|
||||
# define KWSYSPE_PS_COMMAND "ps -Af"
|
||||
# define KWSYSPE_PS_FORMAT "%*d %d %d %*[^\n]\n"
|
||||
#define KWSYSPE_PS_COMMAND "ps -Af"
|
||||
#define KWSYSPE_PS_FORMAT "%*d %d %d %*[^\n]\n"
|
||||
#elif defined(__CYGWIN__)
|
||||
# define KWSYSPE_PS_COMMAND "ps aux"
|
||||
# define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n"
|
||||
#define KWSYSPE_PS_COMMAND "ps aux"
|
||||
#define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2624,11 +2473,10 @@ static void kwsysProcessKill(pid_t process_id)
|
||||
usleep(1);
|
||||
#endif
|
||||
|
||||
/* Kill all children if we can find them. */
|
||||
/* 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")) != NULL) {
|
||||
#if defined(MAXPATHLEN)
|
||||
char fname[MAXPATHLEN];
|
||||
#elif defined(PATH_MAX)
|
||||
@@ -2636,7 +2484,7 @@ static void kwsysProcessKill(pid_t process_id)
|
||||
#else
|
||||
char fname[4096];
|
||||
#endif
|
||||
char buffer[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
char buffer[KWSYSPE_PIPE_BUFFER_SIZE + 1];
|
||||
struct dirent* d;
|
||||
|
||||
/* Each process has a directory in /proc whose name is the pid.
|
||||
@@ -2647,69 +2495,57 @@ static void kwsysProcessKill(pid_t process_id)
|
||||
|
||||
We want to get the ppid for all processes. Those that have
|
||||
process_id as their parent should be recursively killed. */
|
||||
for(d = readdir(procdir); d; d = readdir(procdir))
|
||||
{
|
||||
for (d = readdir(procdir); d; d = readdir(procdir)) {
|
||||
int pid;
|
||||
if(sscanf(d->d_name, "%d", &pid) == 1 && pid != 0)
|
||||
{
|
||||
if (sscanf(d->d_name, "%d", &pid) == 1 && pid != 0) {
|
||||
struct stat finfo;
|
||||
sprintf(fname, "/proc/%d/stat", pid);
|
||||
if(stat(fname, &finfo) == 0)
|
||||
{
|
||||
if (stat(fname, &finfo) == 0) {
|
||||
FILE* f = fopen(fname, "r");
|
||||
if(f)
|
||||
{
|
||||
if (f) {
|
||||
size_t nread = fread(buffer, 1, KWSYSPE_PIPE_BUFFER_SIZE, f);
|
||||
fclose(f);
|
||||
buffer[nread] = '\0';
|
||||
if(nread > 0)
|
||||
{
|
||||
if (nread > 0) {
|
||||
const char* rparen = strrchr(buffer, ')');
|
||||
int ppid;
|
||||
if(rparen && (sscanf(rparen+1, "%*s %d", &ppid) == 1))
|
||||
{
|
||||
if(ppid == process_id)
|
||||
{
|
||||
if (rparen && (sscanf(rparen + 1, "%*s %d", &ppid) == 1)) {
|
||||
if (ppid == process_id) {
|
||||
/* Recursively kill this child and its children. */
|
||||
kwsysProcessKill(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(procdir);
|
||||
}
|
||||
else
|
||||
closedir(procdir);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
#if defined(KWSYSPE_PS_COMMAND)
|
||||
/* Try running "ps" to get the process information. */
|
||||
FILE* ps = popen(KWSYSPE_PS_COMMAND, "r");
|
||||
|
||||
/* Make sure the process started and provided a valid header. */
|
||||
if(ps && fscanf(ps, "%*[^\n]\n") != EOF)
|
||||
{
|
||||
if (ps && fscanf(ps, "%*[^\n]\n") != EOF) {
|
||||
/* Look for processes whose parent is the process being killed. */
|
||||
int pid, ppid;
|
||||
while(fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2)
|
||||
{
|
||||
if(ppid == process_id)
|
||||
{
|
||||
while (fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2) {
|
||||
if (ppid == process_id) {
|
||||
/* Recursively kill this child and its children. */
|
||||
kwsysProcessKill(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We are done with the ps process. */
|
||||
if(ps)
|
||||
{
|
||||
if (ps) {
|
||||
pclose(ps);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Kill the process. */
|
||||
kill(process_id, SIGKILL);
|
||||
@@ -2781,112 +2617,104 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
|
||||
/* Create a pipe through which the signal handler can notify the
|
||||
given process object that a child has exited. */
|
||||
{
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
|
||||
{
|
||||
return 0;
|
||||
/* Create the pipe. */
|
||||
int p[2];
|
||||
if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Store the pipes now to be sure they are cleaned up later. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0];
|
||||
cp->SignalPipe = p[1];
|
||||
/* Store the pipes now to be sure they are cleaned up later. */
|
||||
cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0];
|
||||
cp->SignalPipe = p[1];
|
||||
|
||||
/* Switch the pipe to non-blocking mode so that reading a byte can
|
||||
be an atomic test-and-set. */
|
||||
if(!kwsysProcessSetNonBlocking(p[0]) ||
|
||||
!kwsysProcessSetNonBlocking(p[1]))
|
||||
{
|
||||
return 0;
|
||||
/* Switch the pipe to non-blocking mode so that reading a byte can
|
||||
be an atomic test-and-set. */
|
||||
if (!kwsysProcessSetNonBlocking(p[0]) ||
|
||||
!kwsysProcessSetNonBlocking(p[1])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The children do not need this pipe. Set close-on-exec flag on
|
||||
the pipe's ends. */
|
||||
if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
|
||||
{
|
||||
return 0;
|
||||
/* The children do not need this pipe. Set close-on-exec flag on
|
||||
the pipe's ends. */
|
||||
if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt to add the given signal pipe to the signal handler set. */
|
||||
{
|
||||
|
||||
/* Make sure there is enough space for the new signal pipe. */
|
||||
kwsysProcessInstances oldProcesses = kwsysProcesses;
|
||||
kwsysProcessInstances newProcesses = oldProcesses;
|
||||
if(oldProcesses.Count == oldProcesses.Size)
|
||||
{
|
||||
/* Start with enough space for a small number of process instances
|
||||
and double the size each time more is needed. */
|
||||
newProcesses.Size = oldProcesses.Size? oldProcesses.Size*2 : 4;
|
||||
/* Make sure there is enough space for the new signal pipe. */
|
||||
kwsysProcessInstances oldProcesses = kwsysProcesses;
|
||||
kwsysProcessInstances newProcesses = oldProcesses;
|
||||
if (oldProcesses.Count == oldProcesses.Size) {
|
||||
/* Start with enough space for a small number of process instances
|
||||
and double the size each time more is needed. */
|
||||
newProcesses.Size = oldProcesses.Size ? oldProcesses.Size * 2 : 4;
|
||||
|
||||
/* Try allocating the new block of memory. */
|
||||
if((newProcesses.Processes = ((kwsysProcess**)
|
||||
malloc((size_t)(newProcesses.Size)*
|
||||
sizeof(kwsysProcess*)))))
|
||||
{
|
||||
/* Copy the old pipe set to the new memory. */
|
||||
if(oldProcesses.Count > 0)
|
||||
{
|
||||
memcpy(newProcesses.Processes, oldProcesses.Processes,
|
||||
((size_t)(oldProcesses.Count) * sizeof(kwsysProcess*)));
|
||||
/* Try allocating the new block of memory. */
|
||||
if ((newProcesses.Processes = ((kwsysProcess**)malloc(
|
||||
(size_t)(newProcesses.Size) * sizeof(kwsysProcess*))))) {
|
||||
/* Copy the old pipe set to the new memory. */
|
||||
if (oldProcesses.Count > 0) {
|
||||
memcpy(newProcesses.Processes, oldProcesses.Processes,
|
||||
((size_t)(oldProcesses.Count) * sizeof(kwsysProcess*)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to allocate memory for the new signal pipe set. */
|
||||
return 0;
|
||||
} else {
|
||||
/* Failed to allocate memory for the new signal pipe set. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the new signal pipe to the set. */
|
||||
newProcesses.Processes[newProcesses.Count++] = cp;
|
||||
/* Append the new signal pipe to the set. */
|
||||
newProcesses.Processes[newProcesses.Count++] = cp;
|
||||
|
||||
/* Store the new set in that seen by the signal handler. */
|
||||
kwsysProcessesUpdate(&newProcesses);
|
||||
/* Store the new set in that seen by the signal handler. */
|
||||
kwsysProcessesUpdate(&newProcesses);
|
||||
|
||||
/* Free the original pipes if new ones were allocated. */
|
||||
if(newProcesses.Processes != oldProcesses.Processes)
|
||||
{
|
||||
free(oldProcesses.Processes);
|
||||
/* Free the original pipes if new ones were allocated. */
|
||||
if (newProcesses.Processes != oldProcesses.Processes) {
|
||||
free(oldProcesses.Processes);
|
||||
}
|
||||
|
||||
/* If this is the first process, enable the signal handler. */
|
||||
if(newProcesses.Count == 1)
|
||||
{
|
||||
/* Install our handler for SIGCHLD. Repeat call until it is not
|
||||
interrupted. */
|
||||
struct sigaction newSigAction;
|
||||
memset(&newSigAction, 0, sizeof(struct sigaction));
|
||||
/* If this is the first process, enable the signal handler. */
|
||||
if (newProcesses.Count == 1) {
|
||||
/* Install our handler for SIGCHLD. Repeat call until it is not
|
||||
interrupted. */
|
||||
struct sigaction newSigAction;
|
||||
memset(&newSigAction, 0, sizeof(struct sigaction));
|
||||
#if KWSYSPE_USE_SIGINFO
|
||||
newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
|
||||
newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
|
||||
# ifdef SA_RESTART
|
||||
newSigAction.sa_flags |= SA_RESTART;
|
||||
# endif
|
||||
#else
|
||||
newSigAction.sa_handler = kwsysProcessesSignalHandler;
|
||||
newSigAction.sa_flags = SA_NOCLDSTOP;
|
||||
newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
|
||||
newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
|
||||
#ifdef SA_RESTART
|
||||
newSigAction.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
while((sigaction(SIGCHLD, &newSigAction,
|
||||
&kwsysProcessesOldSigChldAction) < 0) &&
|
||||
(errno == EINTR));
|
||||
#else
|
||||
newSigAction.sa_handler = kwsysProcessesSignalHandler;
|
||||
newSigAction.sa_flags = SA_NOCLDSTOP;
|
||||
#endif
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
while ((sigaction(SIGCHLD, &newSigAction,
|
||||
&kwsysProcessesOldSigChldAction) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
/* Install our handler for SIGINT / SIGTERM. Repeat call until
|
||||
it is not interrupted. */
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
sigaddset(&newSigAction.sa_mask, SIGTERM);
|
||||
while((sigaction(SIGINT, &newSigAction,
|
||||
&kwsysProcessesOldSigIntAction) < 0) &&
|
||||
(errno == EINTR));
|
||||
/* Install our handler for SIGINT / SIGTERM. Repeat call until
|
||||
it is not interrupted. */
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
sigaddset(&newSigAction.sa_mask, SIGTERM);
|
||||
while ((sigaction(SIGINT, &newSigAction,
|
||||
&kwsysProcessesOldSigIntAction) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
sigaddset(&newSigAction.sa_mask, SIGINT);
|
||||
while((sigaction(SIGTERM, &newSigAction,
|
||||
&kwsysProcessesOldSigIntAction) < 0) &&
|
||||
(errno == EINTR));
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
sigaddset(&newSigAction.sa_mask, SIGINT);
|
||||
while ((sigaction(SIGTERM, &newSigAction,
|
||||
&kwsysProcessesOldSigIntAction) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2898,46 +2726,44 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
|
||||
{
|
||||
/* Attempt to remove the given signal pipe from the signal handler set. */
|
||||
{
|
||||
/* Find the given process in the set. */
|
||||
kwsysProcessInstances newProcesses = kwsysProcesses;
|
||||
int i;
|
||||
for(i=0; i < newProcesses.Count; ++i)
|
||||
{
|
||||
if(newProcesses.Processes[i] == cp)
|
||||
{
|
||||
break;
|
||||
/* Find the given process in the set. */
|
||||
kwsysProcessInstances newProcesses = kwsysProcesses;
|
||||
int i;
|
||||
for (i = 0; i < newProcesses.Count; ++i) {
|
||||
if (newProcesses.Processes[i] == cp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < newProcesses.Count)
|
||||
{
|
||||
/* Remove the process from the set. */
|
||||
--newProcesses.Count;
|
||||
for(; i < newProcesses.Count; ++i)
|
||||
{
|
||||
newProcesses.Processes[i] = newProcesses.Processes[i+1];
|
||||
if (i < newProcesses.Count) {
|
||||
/* Remove the process from the set. */
|
||||
--newProcesses.Count;
|
||||
for (; i < newProcesses.Count; ++i) {
|
||||
newProcesses.Processes[i] = newProcesses.Processes[i + 1];
|
||||
}
|
||||
|
||||
/* If this was the last process, disable the signal handler. */
|
||||
if(newProcesses.Count == 0)
|
||||
{
|
||||
/* Restore the signal handlers. Repeat call until it is not
|
||||
interrupted. */
|
||||
while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
|
||||
(errno == EINTR));
|
||||
while((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
|
||||
(errno == EINTR));
|
||||
while((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
|
||||
(errno == EINTR));
|
||||
/* If this was the last process, disable the signal handler. */
|
||||
if (newProcesses.Count == 0) {
|
||||
/* Restore the signal handlers. Repeat call until it is not
|
||||
interrupted. */
|
||||
while ((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
while ((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
while ((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
|
||||
/* Free the table of process pointers since it is now empty.
|
||||
This is safe because the signal handler has been removed. */
|
||||
newProcesses.Size = 0;
|
||||
free(newProcesses.Processes);
|
||||
newProcesses.Processes = 0;
|
||||
/* Free the table of process pointers since it is now empty.
|
||||
This is safe because the signal handler has been removed. */
|
||||
newProcesses.Size = 0;
|
||||
free(newProcesses.Processes);
|
||||
newProcesses.Processes = 0;
|
||||
}
|
||||
|
||||
/* Store the new set in that seen by the signal handler. */
|
||||
kwsysProcessesUpdate(&newProcesses);
|
||||
/* Store the new set in that seen by the signal handler. */
|
||||
kwsysProcessesUpdate(&newProcesses);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2949,9 +2775,10 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void kwsysProcessesSignalHandler(int signum
|
||||
#if KWSYSPE_USE_SIGINFO
|
||||
, siginfo_t* info, void* ucontext
|
||||
,
|
||||
siginfo_t* info, void* ucontext
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
int i, j, procStatus, old_errno = errno;
|
||||
#if KWSYSPE_USE_SIGINFO
|
||||
@@ -2960,99 +2787,97 @@ static void kwsysProcessesSignalHandler(int signum
|
||||
#endif
|
||||
|
||||
/* Signal all process objects that a child has terminated. */
|
||||
switch(signum)
|
||||
{
|
||||
switch (signum) {
|
||||
case SIGCHLD:
|
||||
for(i=0; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
for (i = 0; i < kwsysProcesses.Count; ++i) {
|
||||
/* Set the pipe in a signalled state. */
|
||||
char buf = 1;
|
||||
kwsysProcess* cp = kwsysProcesses.Processes[i];
|
||||
kwsysProcess_ssize_t pipeStatus=
|
||||
kwsysProcess_ssize_t pipeStatus =
|
||||
read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
|
||||
(void)pipeStatus;
|
||||
pipeStatus=write(cp->SignalPipe, &buf, 1);
|
||||
pipeStatus = write(cp->SignalPipe, &buf, 1);
|
||||
(void)pipeStatus;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
/* Signal child processes that are running in new process groups. */
|
||||
for(i=0; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
for (i = 0; i < kwsysProcesses.Count; ++i) {
|
||||
kwsysProcess* cp = kwsysProcesses.Processes[i];
|
||||
/* Check Killed to avoid data race condition when killing.
|
||||
Check State to avoid data race condition in kwsysProcessCleanup
|
||||
when there is an error (it leaves a reaped PID). */
|
||||
if(cp->CreateProcessGroup && !cp->Killed &&
|
||||
cp->State != kwsysProcess_State_Error && cp->ForkPIDs)
|
||||
{
|
||||
for(j=0; j < cp->NumberOfCommands; ++j)
|
||||
{
|
||||
if (cp->CreateProcessGroup && !cp->Killed &&
|
||||
cp->State != kwsysProcess_State_Error && cp->ForkPIDs) {
|
||||
for (j = 0; j < cp->NumberOfCommands; ++j) {
|
||||
/* Make sure the PID is still valid. */
|
||||
if(cp->ForkPIDs[j])
|
||||
{
|
||||
/* The user created a process group for this process. The group ID
|
||||
if (cp->ForkPIDs[j]) {
|
||||
/* The user created a process group for this process. The group
|
||||
ID
|
||||
is the process ID for the original process in the group. */
|
||||
kill(-cp->ForkPIDs[j], SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for all processes to terminate. */
|
||||
while(wait(&procStatus) >= 0 || errno != ECHILD)
|
||||
{
|
||||
}
|
||||
while (wait(&procStatus) >= 0 || errno != ECHILD) {
|
||||
}
|
||||
|
||||
/* Terminate the process, which is now in an inconsistent state
|
||||
because we reaped all the PIDs that it may have been reaping
|
||||
or may have reaped in the future. Reraise the signal so that
|
||||
the proper exit code is returned. */
|
||||
{
|
||||
/* Install default signal handler. */
|
||||
struct sigaction defSigAction;
|
||||
sigset_t unblockSet;
|
||||
memset(&defSigAction, 0, sizeof(defSigAction));
|
||||
defSigAction.sa_handler = SIG_DFL;
|
||||
sigemptyset(&defSigAction.sa_mask);
|
||||
while((sigaction(signum, &defSigAction, 0) < 0) &&
|
||||
(errno == EINTR));
|
||||
/* Unmask the signal. */
|
||||
sigemptyset(&unblockSet);
|
||||
sigaddset(&unblockSet, signum);
|
||||
sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
|
||||
/* Raise the signal again. */
|
||||
raise(signum);
|
||||
/* We shouldn't get here... but if we do... */
|
||||
_exit(1);
|
||||
/* Install default signal handler. */
|
||||
struct sigaction defSigAction;
|
||||
sigset_t unblockSet;
|
||||
memset(&defSigAction, 0, sizeof(defSigAction));
|
||||
defSigAction.sa_handler = SIG_DFL;
|
||||
sigemptyset(&defSigAction.sa_mask);
|
||||
while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR))
|
||||
;
|
||||
/* Unmask the signal. */
|
||||
sigemptyset(&unblockSet);
|
||||
sigaddset(&unblockSet, signum);
|
||||
sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
|
||||
/* Raise the signal again. */
|
||||
raise(signum);
|
||||
/* We shouldn't get here... but if we do... */
|
||||
_exit(1);
|
||||
}
|
||||
/* break omitted to silence unreachable code clang compiler warning. */
|
||||
}
|
||||
}
|
||||
|
||||
#if !KWSYSPE_USE_SIGINFO
|
||||
/* Re-Install our handler. Repeat call until it is not interrupted. */
|
||||
{
|
||||
struct sigaction newSigAction;
|
||||
struct sigaction &oldSigAction;
|
||||
memset(&newSigAction, 0, sizeof(struct sigaction));
|
||||
newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
|
||||
newSigChldAction.sa_flags = SA_NOCLDSTOP;
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
switch(signum)
|
||||
{
|
||||
case SIGCHLD: oldSigAction = &kwsysProcessesOldSigChldAction; break;
|
||||
case SIGINT:
|
||||
sigaddset(&newSigAction.sa_mask, SIGTERM);
|
||||
oldSigAction = &kwsysProcessesOldSigIntAction; break;
|
||||
case SIGTERM:
|
||||
sigaddset(&newSigAction.sa_mask, SIGINT);
|
||||
oldSigAction = &kwsysProcessesOldSigTermAction; break;
|
||||
default: return 0;
|
||||
struct sigaction newSigAction;
|
||||
struct sigaction& oldSigAction;
|
||||
memset(&newSigAction, 0, sizeof(struct sigaction));
|
||||
newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
|
||||
newSigChldAction.sa_flags = SA_NOCLDSTOP;
|
||||
sigemptyset(&newSigAction.sa_mask);
|
||||
switch (signum) {
|
||||
case SIGCHLD:
|
||||
oldSigAction = &kwsysProcessesOldSigChldAction;
|
||||
break;
|
||||
case SIGINT:
|
||||
sigaddset(&newSigAction.sa_mask, SIGTERM);
|
||||
oldSigAction = &kwsysProcessesOldSigIntAction;
|
||||
break;
|
||||
case SIGTERM:
|
||||
sigaddset(&newSigAction.sa_mask, SIGINT);
|
||||
oldSigAction = &kwsysProcessesOldSigTermAction;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
while((sigaction(signum, &newSigAction,
|
||||
oldSigAction) < 0) &&
|
||||
(errno == EINTR));
|
||||
while ((sigaction(signum, &newSigAction, oldSigAction) < 0) &&
|
||||
(errno == EINTR))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3062,10 +2887,9 @@ static void kwsysProcessesSignalHandler(int signum
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_ResetStartTime(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Reset start time. */
|
||||
cp->StartTime = kwsysProcessTimeGetCurrent();
|
||||
}
|
||||
+795
-1040
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Process.h)
|
||||
#include KWSYS_HEADER(Encoding.h)
|
||||
@@ -16,8 +7,8 @@
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Process.h.in"
|
||||
# include "Encoding.h.in"
|
||||
#include "Encoding.h.in"
|
||||
#include "Process.h.in"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -31,15 +22,15 @@ a UNIX-style select system call.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push, 1)
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
#include <windows.h> /* Windows API */
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
#define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
#endif
|
||||
#include <string.h> /* strlen, strdup */
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <io.h> /* _unlink */
|
||||
#include <io.h> /* _unlink */
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <string.h> /* strlen, strdup */
|
||||
#ifdef __WATCOMC__
|
||||
#define _unlink unlink
|
||||
#endif
|
||||
@@ -52,14 +43,14 @@ a UNIX-style select system call.
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#pragma warning (disable: 4514)
|
||||
#pragma warning (disable: 4706)
|
||||
#pragma warning(pop)
|
||||
#pragma warning(disable : 4514)
|
||||
#pragma warning(disable : 4706)
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
# pragma warn -8004 /* assigned a value that is never used */
|
||||
# pragma warn -8060 /* Assignment inside if() condition. */
|
||||
#pragma warn - 8004 /* assigned a value that is never used */
|
||||
#pragma warn - 8060 /* Assignment inside if() condition. */
|
||||
#endif
|
||||
|
||||
/* There are pipes for the process pipeline's stdout and stderr. */
|
||||
@@ -72,18 +63,14 @@ a UNIX-style select system call.
|
||||
|
||||
/* Debug output macro. */
|
||||
#if 0
|
||||
# define KWSYSPE_DEBUG(x) \
|
||||
( \
|
||||
(void*)cp == (void*)0x00226DE0? \
|
||||
( \
|
||||
fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, __LINE__), \
|
||||
fprintf x, \
|
||||
fflush(stderr), \
|
||||
1 \
|
||||
) : (1) \
|
||||
)
|
||||
#define KWSYSPE_DEBUG(x) \
|
||||
((void*)cp == (void*)0x00226DE0 \
|
||||
? (fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, \
|
||||
__LINE__), \
|
||||
fprintf x, fflush(stderr), 1) \
|
||||
: (1))
|
||||
#else
|
||||
# define KWSYSPE_DEBUG(x) (void)1
|
||||
#define KWSYSPE_DEBUG(x) (void)1
|
||||
#endif
|
||||
|
||||
typedef LARGE_INTEGER kwsysProcessTime;
|
||||
@@ -99,7 +86,6 @@ typedef struct kwsysProcessCreateInformation_s
|
||||
HANDLE hStdError;
|
||||
} kwsysProcessCreateInformation;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
|
||||
static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
|
||||
@@ -112,8 +98,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp);
|
||||
static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
|
||||
kwsysProcessCreateInformation* si);
|
||||
static void kwsysProcessDestroy(kwsysProcess* cp, int event);
|
||||
static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle,
|
||||
const char* name);
|
||||
static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
|
||||
static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
|
||||
static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
|
||||
static void kwsysProcessCleanupHandle(PHANDLE h);
|
||||
@@ -129,8 +114,10 @@ static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
|
||||
static double kwsysProcessTimeToDouble(kwsysProcessTime t);
|
||||
static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
|
||||
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2);
|
||||
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2);
|
||||
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
|
||||
static void kwsysProcessKillTree(int pid);
|
||||
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
|
||||
@@ -300,10 +287,10 @@ struct kwsysProcess_s
|
||||
int PipesLeft;
|
||||
|
||||
/* Buffer for error messages. */
|
||||
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1];
|
||||
|
||||
/* Description for the ExitException. */
|
||||
char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1];
|
||||
|
||||
/* Windows process information data. */
|
||||
PROCESS_INFORMATION* ProcessInformation;
|
||||
@@ -337,18 +324,16 @@ kwsysProcess* kwsysProcess_New(void)
|
||||
first process. This prevents the risk of an orphaned process being
|
||||
started by the main thread while the default Ctrl handler is in
|
||||
progress. */
|
||||
if(!kwsysProcessesInitialize())
|
||||
{
|
||||
if (!kwsysProcessesInitialize()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate a process control structure. */
|
||||
cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
/* Could not allocate memory for the control structure. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ZeroMemory(cp, sizeof(*cp));
|
||||
|
||||
/* Share stdin with the parent process by default. */
|
||||
@@ -362,42 +347,38 @@ kwsysProcess* kwsysProcess_New(void)
|
||||
ZeroMemory(&osv, sizeof(osv));
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
# pragma warning (push)
|
||||
# ifdef __INTEL_COMPILER
|
||||
# pragma warning (disable:1478)
|
||||
# else
|
||||
# pragma warning (disable:4996)
|
||||
# endif
|
||||
#pragma warning(push)
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning(disable : 1478)
|
||||
#else
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
#endif
|
||||
GetVersionEx(&osv);
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
|
||||
{
|
||||
if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
|
||||
/* Win9x no longer supported. */
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initially no thread owns the mutex. Initialize semaphore to 1. */
|
||||
if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
|
||||
{
|
||||
if (!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initially no data are available. Initialize semaphore to 0. */
|
||||
if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Full = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the thread to read each pipe. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
DWORD dummy=0;
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
DWORD dummy = 0;
|
||||
|
||||
/* Assign the thread its index. */
|
||||
cp->Pipe[i].Index = i;
|
||||
@@ -406,73 +387,62 @@ kwsysProcess* kwsysProcess_New(void)
|
||||
cp->Pipe[i].Process = cp;
|
||||
|
||||
/* No process is yet running. Initialize semaphore to 0. */
|
||||
if(!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The pipe is not yet reset. Initialize semaphore to 0. */
|
||||
if(!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The thread's buffer is initially empty. Initialize semaphore to 1. */
|
||||
if(!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the reading thread. It will block immediately. The
|
||||
thread will not make deeply nested calls, so we need only a
|
||||
small stack. */
|
||||
if(!(cp->Pipe[i].Reader.Thread = CreateThread(0, 1024,
|
||||
kwsysProcessPipeThreadRead,
|
||||
&cp->Pipe[i], 0, &dummy)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Reader.Thread = CreateThread(
|
||||
0, 1024, kwsysProcessPipeThreadRead, &cp->Pipe[i], 0, &dummy))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* No process is yet running. Initialize semaphore to 0. */
|
||||
if(!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The pipe is not yet reset. Initialize semaphore to 0. */
|
||||
if(!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The waker should not wake immediately. Initialize semaphore to 0. */
|
||||
if(!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the waking thread. It will block immediately. The
|
||||
thread will not make deeply nested calls, so we need only a
|
||||
small stack. */
|
||||
if(!(cp->Pipe[i].Waker.Thread = CreateThread(0, 1024,
|
||||
kwsysProcessPipeThreadWake,
|
||||
&cp->Pipe[i], 0, &dummy)))
|
||||
{
|
||||
if (!(cp->Pipe[i].Waker.Thread = CreateThread(
|
||||
0, 1024, kwsysProcessPipeThreadWake, &cp->Pipe[i], 0, &dummy))) {
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(i=0; i < 3; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return cp;
|
||||
}
|
||||
@@ -483,33 +453,26 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Make sure we have an instance. */
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the process is executing, wait for it to finish. */
|
||||
if(cp->State == kwsysProcess_State_Executing)
|
||||
{
|
||||
if(cp->Detached)
|
||||
{
|
||||
if (cp->State == kwsysProcess_State_Executing) {
|
||||
if (cp->Detached) {
|
||||
kwsysProcess_Disown(cp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
kwsysProcess_WaitForExit(cp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We are deleting the kwsysProcess instance. */
|
||||
cp->Deleting = 1;
|
||||
|
||||
/* Terminate each of the threads. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
/* Terminate this reading thread. */
|
||||
if(cp->Pipe[i].Reader.Thread)
|
||||
{
|
||||
if (cp->Pipe[i].Reader.Thread) {
|
||||
/* Signal the thread we are ready for it. It will terminate
|
||||
immediately since Deleting is set. */
|
||||
ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
|
||||
@@ -519,11 +482,10 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
|
||||
/* Close the handle to the thread. */
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread);
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate this waking thread. */
|
||||
if(cp->Pipe[i].Waker.Thread)
|
||||
{
|
||||
if (cp->Pipe[i].Waker.Thread) {
|
||||
/* Signal the thread we are ready for it. It will terminate
|
||||
immediately since Deleting is set. */
|
||||
ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
|
||||
@@ -533,7 +495,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
|
||||
/* Close the handle to the thread. */
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup the pipe's semaphores. */
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready);
|
||||
@@ -542,7 +504,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready);
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go);
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the shared semaphores. */
|
||||
kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
|
||||
@@ -554,10 +516,9 @@ 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)
|
||||
{
|
||||
if (cp->CommandExitCodes) {
|
||||
free(cp->CommandExitCodes);
|
||||
}
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
|
||||
@@ -565,24 +526,20 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
||||
int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
|
||||
{
|
||||
int i;
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
free(cp->Commands[i]);
|
||||
}
|
||||
}
|
||||
cp->NumberOfCommands = 0;
|
||||
if(cp->Commands)
|
||||
{
|
||||
if (cp->Commands) {
|
||||
free(cp->Commands);
|
||||
cp->Commands = 0;
|
||||
}
|
||||
if(command)
|
||||
{
|
||||
}
|
||||
if (command) {
|
||||
return kwsysProcess_AddCommand(cp, command);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -593,91 +550,87 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
||||
wchar_t** newCommands;
|
||||
|
||||
/* Make sure we have a command to add. */
|
||||
if(!cp || !command || !*command)
|
||||
{
|
||||
if (!cp || !command || !*command) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Allocate a new array for command pointers. */
|
||||
newNumberOfCommands = cp->NumberOfCommands + 1;
|
||||
if(!(newCommands = (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands)))
|
||||
{
|
||||
if (!(newCommands =
|
||||
(wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands))) {
|
||||
/* Out of memory. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy any existing commands into the new array. */
|
||||
{
|
||||
int i;
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
newCommands[i] = cp->Commands[i];
|
||||
int i;
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
newCommands[i] = cp->Commands[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (cp->Verbatim)
|
||||
{
|
||||
if (cp->Verbatim) {
|
||||
/* Copy the verbatim command line into the buffer. */
|
||||
newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Encode the arguments so CommandLineToArgvW can decode
|
||||
them from the command line string in the child. */
|
||||
char buffer[32768]; /* CreateProcess max command-line length. */
|
||||
char* end = buffer + sizeof(buffer);
|
||||
char* out = buffer;
|
||||
char const* const* a;
|
||||
for (a = command; *a; ++a)
|
||||
{
|
||||
for (a = command; *a; ++a) {
|
||||
int quote = !**a; /* Quote the empty string. */
|
||||
int slashes = 0;
|
||||
char const* c;
|
||||
if (a != command && out != end) { *out++ = ' '; }
|
||||
for (c = *a; !quote && *c; ++c)
|
||||
{ quote = (*c == ' ' || *c == '\t'); }
|
||||
if (quote && out != end) { *out++ = '"'; }
|
||||
for (c = *a; *c; ++c)
|
||||
{
|
||||
if (*c == '\\')
|
||||
{
|
||||
if (a != command && out != end) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
for (c = *a; !quote && *c; ++c) {
|
||||
quote = (*c == ' ' || *c == '\t');
|
||||
}
|
||||
if (quote && out != end) {
|
||||
*out++ = '"';
|
||||
}
|
||||
for (c = *a; *c; ++c) {
|
||||
if (*c == '\\') {
|
||||
++slashes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*c == '"')
|
||||
{
|
||||
} else {
|
||||
if (*c == '"') {
|
||||
// Add n+1 backslashes to total 2n+1 before internal '"'.
|
||||
while(slashes-- >= 0 && out != end) { *out++ = '\\'; }
|
||||
while (slashes-- >= 0 && out != end) {
|
||||
*out++ = '\\';
|
||||
}
|
||||
slashes = 0;
|
||||
}
|
||||
if (out != end) { *out++ = *c; }
|
||||
slashes = 0;
|
||||
}
|
||||
if (quote)
|
||||
{
|
||||
if (out != end) {
|
||||
*out++ = *c;
|
||||
}
|
||||
}
|
||||
if (quote) {
|
||||
// Add n backslashes to total 2n before ending '"'.
|
||||
while (slashes-- > 0 && out != end) { *out++ = '\\'; }
|
||||
if (out != end) { *out++ = '"'; }
|
||||
while (slashes-- > 0 && out != end) {
|
||||
*out++ = '\\';
|
||||
}
|
||||
if (out != end) {
|
||||
*out++ = '"';
|
||||
}
|
||||
}
|
||||
if(out != end)
|
||||
{
|
||||
*out = '\0';
|
||||
newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
newCommands[cp->NumberOfCommands] = 0;
|
||||
}
|
||||
}
|
||||
if (!newCommands[cp->NumberOfCommands])
|
||||
{
|
||||
if (out != end) {
|
||||
*out = '\0';
|
||||
newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
|
||||
} else {
|
||||
newCommands[cp->NumberOfCommands] = 0;
|
||||
}
|
||||
}
|
||||
if (!newCommands[cp->NumberOfCommands]) {
|
||||
/* Out of memory or command line too long. */
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the new array of commands. */
|
||||
free(cp->Commands);
|
||||
@@ -689,15 +642,13 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cp->Timeout = timeout;
|
||||
if(cp->Timeout < 0)
|
||||
{
|
||||
if (cp->Timeout < 0) {
|
||||
cp->Timeout = 0;
|
||||
}
|
||||
}
|
||||
// Force recomputation of TimeoutTime.
|
||||
cp->TimeoutTime.QuadPart = -1;
|
||||
}
|
||||
@@ -705,38 +656,32 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
if(cp->WorkingDirectory)
|
||||
{
|
||||
}
|
||||
if (cp->WorkingDirectory) {
|
||||
free(cp->WorkingDirectory);
|
||||
cp->WorkingDirectory = 0;
|
||||
}
|
||||
if(dir && dir[0])
|
||||
{
|
||||
}
|
||||
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);
|
||||
if(length > 0)
|
||||
{
|
||||
wchar_t* work_dir = malloc(length*sizeof(wchar_t));
|
||||
if(!work_dir)
|
||||
{
|
||||
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, 0)) {
|
||||
free(work_dir);
|
||||
free(wdir);
|
||||
return 0;
|
||||
}
|
||||
cp->WorkingDirectory = work_dir;
|
||||
}
|
||||
free(wdir);
|
||||
cp->WorkingDirectory = work_dir;
|
||||
}
|
||||
free(wdir);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -744,39 +689,40 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
|
||||
int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
|
||||
{
|
||||
char** pfile;
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
switch(pipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
|
||||
case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
|
||||
case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
|
||||
default: return 0;
|
||||
}
|
||||
if(*pfile)
|
||||
{
|
||||
}
|
||||
switch (pipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
pfile = &cp->PipeFileSTDIN;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
pfile = &cp->PipeFileSTDOUT;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
pfile = &cp->PipeFileSTDERR;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (*pfile) {
|
||||
free(*pfile);
|
||||
*pfile = 0;
|
||||
}
|
||||
if(file)
|
||||
{
|
||||
*pfile = (char*)malloc(strlen(file)+1);
|
||||
if(!*pfile)
|
||||
{
|
||||
}
|
||||
if (file) {
|
||||
*pfile = (char*)malloc(strlen(file) + 1);
|
||||
if (!*pfile) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(*pfile, file);
|
||||
}
|
||||
strcpy(*pfile, file);
|
||||
}
|
||||
|
||||
/* If we are redirecting the pipe, do not share it or use a native
|
||||
pipe. */
|
||||
if(*pfile)
|
||||
{
|
||||
if (*pfile) {
|
||||
kwsysProcess_SetPipeNative(cp, pipe, 0);
|
||||
kwsysProcess_SetPipeShared(cp, pipe, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -784,26 +730,30 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(pipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
|
||||
case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
|
||||
case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
|
||||
default: return;
|
||||
}
|
||||
switch (pipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
cp->PipeSharedSTDIN = shared ? 1 : 0;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
cp->PipeSharedSTDOUT = shared ? 1 : 0;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
cp->PipeSharedSTDERR = shared ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we are sharing the pipe, do not redirect it to a file or use a
|
||||
native pipe. */
|
||||
if(shared)
|
||||
{
|
||||
if (shared) {
|
||||
kwsysProcess_SetPipeFile(cp, pipe, 0);
|
||||
kwsysProcess_SetPipeNative(cp, pipe, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -811,129 +761,135 @@ void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
|
||||
{
|
||||
HANDLE* pPipeNative = 0;
|
||||
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(pipe)
|
||||
{
|
||||
case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
|
||||
case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
|
||||
case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
|
||||
default: return;
|
||||
}
|
||||
switch (pipe) {
|
||||
case kwsysProcess_Pipe_STDIN:
|
||||
pPipeNative = cp->PipeNativeSTDIN;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDOUT:
|
||||
pPipeNative = cp->PipeNativeSTDOUT;
|
||||
break;
|
||||
case kwsysProcess_Pipe_STDERR:
|
||||
pPipeNative = cp->PipeNativeSTDERR;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the native pipe handles provided. */
|
||||
if(p)
|
||||
{
|
||||
if (p) {
|
||||
pPipeNative[0] = p[0];
|
||||
pPipeNative[1] = p[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pPipeNative[0] = 0;
|
||||
pPipeNative[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are using a native pipe, do not share it or redirect it to
|
||||
a file. */
|
||||
if(p)
|
||||
{
|
||||
if (p) {
|
||||
kwsysProcess_SetPipeFile(cp, pipe, 0);
|
||||
kwsysProcess_SetPipeShared(cp, pipe, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(optionId)
|
||||
{
|
||||
case kwsysProcess_Option_Detach: return cp->OptionDetach;
|
||||
case kwsysProcess_Option_HideWindow: return cp->HideWindow;
|
||||
case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
|
||||
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
|
||||
switch (optionId) {
|
||||
case kwsysProcess_Option_Detach:
|
||||
return cp->OptionDetach;
|
||||
case kwsysProcess_Option_HideWindow:
|
||||
return cp->HideWindow;
|
||||
case kwsysProcess_Option_MergeOutput:
|
||||
return cp->MergeOutput;
|
||||
case kwsysProcess_Option_Verbatim:
|
||||
return cp->Verbatim;
|
||||
case kwsysProcess_Option_CreateProcessGroup:
|
||||
return cp->CreateProcessGroup;
|
||||
default: return 0;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(optionId)
|
||||
{
|
||||
case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
|
||||
case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
|
||||
case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
|
||||
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
|
||||
switch (optionId) {
|
||||
case kwsysProcess_Option_Detach:
|
||||
cp->OptionDetach = value;
|
||||
break;
|
||||
case kwsysProcess_Option_HideWindow:
|
||||
cp->HideWindow = value;
|
||||
break;
|
||||
case kwsysProcess_Option_MergeOutput:
|
||||
cp->MergeOutput = value;
|
||||
break;
|
||||
case kwsysProcess_Option_Verbatim:
|
||||
cp->Verbatim = value;
|
||||
break;
|
||||
case kwsysProcess_Option_CreateProcessGroup:
|
||||
cp->CreateProcessGroup = value; break;
|
||||
default: break;
|
||||
}
|
||||
cp->CreateProcessGroup = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetState(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->State : kwsysProcess_State_Error;
|
||||
return cp ? cp->State : kwsysProcess_State_Error;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitException(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitException : kwsysProcess_Exception_Other;
|
||||
return cp ? cp->ExitException : kwsysProcess_Exception_Other;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitValue(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitValue : -1;
|
||||
return cp ? cp->ExitValue : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int kwsysProcess_GetExitCode(kwsysProcess* cp)
|
||||
{
|
||||
return cp? cp->ExitCode : 0;
|
||||
return cp ? cp->ExitCode : 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return "Process management structure could not be allocated";
|
||||
}
|
||||
else if(cp->State == kwsysProcess_State_Error)
|
||||
{
|
||||
} else if (cp->State == kwsysProcess_State_Error) {
|
||||
return cp->ErrorMessage;
|
||||
}
|
||||
}
|
||||
return "Success";
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return "GetExceptionString called with NULL process management structure";
|
||||
}
|
||||
else if(cp->State == kwsysProcess_State_Exception)
|
||||
{
|
||||
} else if (cp->State == kwsysProcess_State_Exception) {
|
||||
return cp->ExitExceptionString;
|
||||
}
|
||||
}
|
||||
return "No exception";
|
||||
}
|
||||
|
||||
@@ -943,259 +899,210 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Do not execute a second time. */
|
||||
if(!cp || cp->State == kwsysProcess_State_Executing)
|
||||
{
|
||||
if (!cp || cp->State == kwsysProcess_State_Executing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have something to run. */
|
||||
if(cp->NumberOfCommands < 1)
|
||||
{
|
||||
if (cp->NumberOfCommands < 1) {
|
||||
strcpy(cp->ErrorMessage, "No command");
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the control structure for a new process. */
|
||||
if(!kwsysProcessInitialize(cp))
|
||||
{
|
||||
if (!kwsysProcessInitialize(cp)) {
|
||||
strcpy(cp->ErrorMessage, "Out of memory");
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the real working directory of this process and change to
|
||||
the working directory for the child processes. This is needed
|
||||
to make pipe file paths evaluate correctly. */
|
||||
if(cp->WorkingDirectory)
|
||||
{
|
||||
if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
|
||||
cp->RealWorkingDirectory))
|
||||
{
|
||||
if (cp->WorkingDirectory) {
|
||||
if (!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
|
||||
cp->RealWorkingDirectory)) {
|
||||
kwsysProcessCleanup(cp, GetLastError());
|
||||
return;
|
||||
}
|
||||
SetCurrentDirectoryW(cp->WorkingDirectory);
|
||||
}
|
||||
|
||||
SetCurrentDirectoryW(cp->WorkingDirectory);
|
||||
}
|
||||
|
||||
/* Setup the stdin pipe for the first process. */
|
||||
if(cp->PipeFileSTDIN)
|
||||
{
|
||||
if (cp->PipeFileSTDIN) {
|
||||
/* Create a handle to read a file for stdin. */
|
||||
wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
|
||||
DWORD error;
|
||||
cp->PipeChildStd[0] =
|
||||
CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
0, OPEN_EXISTING, 0, 0);
|
||||
CreateFileW(wstdin, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
error = GetLastError(); /* Check now in case free changes this. */
|
||||
free(wstdin);
|
||||
if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) {
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(cp->PipeSharedSTDIN)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDIN) {
|
||||
/* Share this process's stdin with the child. */
|
||||
kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]);
|
||||
}
|
||||
else if(cp->PipeNativeSTDIN[0])
|
||||
{
|
||||
} else if (cp->PipeNativeSTDIN[0]) {
|
||||
/* Use the provided native pipe. */
|
||||
kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Explicitly give the child no stdin. */
|
||||
cp->PipeChildStd[0] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the output pipe for the last process.
|
||||
We always create this so the pipe thread can run even if we
|
||||
do not end up giving the write end to the child below. */
|
||||
if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
|
||||
&cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0))
|
||||
{
|
||||
if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
|
||||
&cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0)) {
|
||||
kwsysProcessCleanup(cp, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(cp->PipeFileSTDOUT)
|
||||
{
|
||||
if (cp->PipeFileSTDOUT) {
|
||||
/* Use a file for stdout. */
|
||||
DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
|
||||
cp->PipeFileSTDOUT);
|
||||
if(error)
|
||||
{
|
||||
if (error) {
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(cp->PipeSharedSTDOUT)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDOUT) {
|
||||
/* Use the parent stdout. */
|
||||
kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]);
|
||||
}
|
||||
else if(cp->PipeNativeSTDOUT[1])
|
||||
{
|
||||
} else if (cp->PipeNativeSTDOUT[1]) {
|
||||
/* Use the given handle for stdout. */
|
||||
kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Use our pipe for stdout. Duplicate the handle since our waker
|
||||
thread will use the original. Do not make it inherited yet. */
|
||||
if(!DuplicateHandle(GetCurrentProcess(),
|
||||
cp->Pipe[KWSYSPE_PIPE_STDOUT].Write,
|
||||
GetCurrentProcess(), &cp->PipeChildStd[1],
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
if (!DuplicateHandle(GetCurrentProcess(),
|
||||
cp->Pipe[KWSYSPE_PIPE_STDOUT].Write,
|
||||
GetCurrentProcess(), &cp->PipeChildStd[1], 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
kwsysProcessCleanup(cp, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create stderr pipe to be shared by all processes in the pipeline.
|
||||
We always create this so the pipe thread can run even if we do not
|
||||
end up giving the write end to the child below. */
|
||||
if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
|
||||
&cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
|
||||
{
|
||||
if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
|
||||
&cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0)) {
|
||||
kwsysProcessCleanup(cp, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(cp->PipeFileSTDERR)
|
||||
{
|
||||
if (cp->PipeFileSTDERR) {
|
||||
/* Use a file for stderr. */
|
||||
DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
|
||||
cp->PipeFileSTDERR);
|
||||
if(error)
|
||||
{
|
||||
if (error) {
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(cp->PipeSharedSTDERR)
|
||||
{
|
||||
} else if (cp->PipeSharedSTDERR) {
|
||||
/* Use the parent stderr. */
|
||||
kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]);
|
||||
}
|
||||
else if(cp->PipeNativeSTDERR[1])
|
||||
{
|
||||
} else if (cp->PipeNativeSTDERR[1]) {
|
||||
/* Use the given handle for stderr. */
|
||||
kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Use our pipe for stderr. Duplicate the handle since our waker
|
||||
thread will use the original. Do not make it inherited yet. */
|
||||
if(!DuplicateHandle(GetCurrentProcess(),
|
||||
cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
|
||||
GetCurrentProcess(), &cp->PipeChildStd[2],
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
if (!DuplicateHandle(GetCurrentProcess(),
|
||||
cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
|
||||
GetCurrentProcess(), &cp->PipeChildStd[2], 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
kwsysProcessCleanup(cp, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the pipeline of processes. */
|
||||
{
|
||||
/* Child startup control data. */
|
||||
kwsysProcessCreateInformation si;
|
||||
HANDLE nextStdInput = cp->PipeChildStd[0];
|
||||
/* Child startup control data. */
|
||||
kwsysProcessCreateInformation si;
|
||||
HANDLE nextStdInput = cp->PipeChildStd[0];
|
||||
|
||||
/* Initialize startup info data. */
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.StartupInfo.cb = sizeof(si.StartupInfo);
|
||||
/* Initialize startup info data. */
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.StartupInfo.cb = sizeof(si.StartupInfo);
|
||||
|
||||
/* Decide whether a child window should be shown. */
|
||||
si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
si.StartupInfo.wShowWindow =
|
||||
(unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
|
||||
/* Decide whether a child window should be shown. */
|
||||
si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
si.StartupInfo.wShowWindow =
|
||||
(unsigned short)(cp->HideWindow ? SW_HIDE : SW_SHOWDEFAULT);
|
||||
|
||||
/* Connect the child's output pipes to the threads. */
|
||||
si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
/* Connect the child's output pipes to the threads. */
|
||||
si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
/* Setup the process's pipes. */
|
||||
si.hStdInput = nextStdInput;
|
||||
if (i == cp->NumberOfCommands-1)
|
||||
{
|
||||
/* The last child gets the overall stdout. */
|
||||
nextStdInput = INVALID_HANDLE_VALUE;
|
||||
si.hStdOutput = cp->PipeChildStd[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a pipe to sit between the children. */
|
||||
HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
|
||||
if (!CreatePipe(&p[0], &p[1], 0, 0))
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (nextStdInput != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupHandle(&nextStdInput);
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
/* Setup the process's pipes. */
|
||||
si.hStdInput = nextStdInput;
|
||||
if (i == cp->NumberOfCommands - 1) {
|
||||
/* The last child gets the overall stdout. */
|
||||
nextStdInput = INVALID_HANDLE_VALUE;
|
||||
si.hStdOutput = cp->PipeChildStd[1];
|
||||
} else {
|
||||
/* Create a pipe to sit between the children. */
|
||||
HANDLE p[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
||||
if (!CreatePipe(&p[0], &p[1], 0, 0)) {
|
||||
DWORD error = GetLastError();
|
||||
if (nextStdInput != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupHandle(&nextStdInput);
|
||||
}
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
nextStdInput = p[0];
|
||||
si.hStdOutput = p[1];
|
||||
nextStdInput = p[0];
|
||||
si.hStdOutput = p[1];
|
||||
}
|
||||
si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
|
||||
si.hStdError =
|
||||
cp->MergeOutput ? cp->PipeChildStd[1] : cp->PipeChildStd[2];
|
||||
|
||||
{
|
||||
DWORD error = kwsysProcessCreate(cp, i, &si);
|
||||
{
|
||||
DWORD error = kwsysProcessCreate(cp, i, &si);
|
||||
|
||||
/* Close our copies of pipes used between children. */
|
||||
if (si.hStdInput != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupHandle(&si.hStdInput);
|
||||
}
|
||||
if (si.hStdOutput != cp->PipeChildStd[1])
|
||||
{
|
||||
kwsysProcessCleanupHandle(&si.hStdOutput);
|
||||
}
|
||||
if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput)
|
||||
{
|
||||
kwsysProcessCleanupHandle(&si.hStdError);
|
||||
}
|
||||
if (!error)
|
||||
{
|
||||
cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextStdInput != cp->PipeChildStd[0])
|
||||
{
|
||||
kwsysProcessCleanupHandle(&nextStdInput);
|
||||
/* Close our copies of pipes used between children. */
|
||||
if (si.hStdInput != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupHandle(&si.hStdInput);
|
||||
}
|
||||
if (si.hStdOutput != cp->PipeChildStd[1]) {
|
||||
kwsysProcessCleanupHandle(&si.hStdOutput);
|
||||
}
|
||||
if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput) {
|
||||
kwsysProcessCleanupHandle(&si.hStdError);
|
||||
}
|
||||
if (!error) {
|
||||
cp->ProcessEvents[i + 1] = cp->ProcessInformation[i].hProcess;
|
||||
} else {
|
||||
if (nextStdInput != cp->PipeChildStd[0]) {
|
||||
kwsysProcessCleanupHandle(&nextStdInput);
|
||||
}
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
kwsysProcessCleanup(cp, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The parent process does not need the child's pipe ends. */
|
||||
for (i=0; i < 3; ++i)
|
||||
{
|
||||
for (i = 0; i < 3; ++i) {
|
||||
kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the working directory. */
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
if (cp->RealWorkingDirectory) {
|
||||
SetCurrentDirectoryW(cp->RealWorkingDirectory);
|
||||
free(cp->RealWorkingDirectory);
|
||||
cp->RealWorkingDirectory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The timeout period starts now. */
|
||||
cp->StartTime = kwsysProcessTimeGetCurrent();
|
||||
@@ -1203,24 +1110,21 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
||||
|
||||
/* All processes in the pipeline have been started in suspended
|
||||
mode. Resume them all now. */
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
ResumeThread(cp->ProcessInformation[i].hThread);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
|
||||
/* Tell the pipe threads that a process has started. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
|
||||
ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't care about the children's main threads. */
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
|
||||
}
|
||||
}
|
||||
|
||||
/* No pipe has reported data. */
|
||||
cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
|
||||
@@ -1237,21 +1141,19 @@ void kwsysProcess_Disown(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* Make sure we are executing a detached process. */
|
||||
if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
|
||||
cp->TimeoutExpired || cp->Killed || cp->Terminated)
|
||||
{
|
||||
if (!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
|
||||
cp->TimeoutExpired || cp->Killed || cp->Terminated) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the reading threads. */
|
||||
kwsysProcessDisablePipeThreads(cp);
|
||||
|
||||
/* Wait for all pipe threads to reset. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
|
||||
WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
/* We will not wait for exit, so cleanup now. */
|
||||
kwsysProcessCleanup(cp, 0);
|
||||
@@ -1276,11 +1178,10 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
|
||||
DWORD w;
|
||||
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
|
||||
cp->TimeoutExpired)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
|
||||
cp->TimeoutExpired) {
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the time at which user timeout period starts. */
|
||||
userStartTime = kwsysProcessTimeGetCurrent();
|
||||
@@ -1290,125 +1191,102 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
|
||||
user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
|
||||
|
||||
/* Loop until we have a reason to return. */
|
||||
while(!done && cp->PipesLeft > 0)
|
||||
{
|
||||
while (!done && cp->PipesLeft > 0) {
|
||||
/* If we previously got data from a thread, let it know we are
|
||||
done with the data. */
|
||||
if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
|
||||
{
|
||||
if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
|
||||
KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
|
||||
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
|
||||
cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup a timeout if required. */
|
||||
if(kwsysProcessGetTimeoutLeft(&timeoutTime, user?userTimeout:0,
|
||||
&timeoutLength))
|
||||
{
|
||||
if (kwsysProcessGetTimeoutLeft(&timeoutTime, user ? userTimeout : 0,
|
||||
&timeoutLength)) {
|
||||
/* Timeout has already expired. */
|
||||
expired = 1;
|
||||
break;
|
||||
}
|
||||
if(timeoutTime.QuadPart < 0)
|
||||
{
|
||||
}
|
||||
if (timeoutTime.QuadPart < 0) {
|
||||
timeout = INFINITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
timeout = kwsysProcessTimeToDWORD(timeoutLength);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for a pipe's thread to signal or a process to terminate. */
|
||||
w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents,
|
||||
0, timeout);
|
||||
if(w == WAIT_TIMEOUT)
|
||||
{
|
||||
w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents, 0,
|
||||
timeout);
|
||||
if (w == WAIT_TIMEOUT) {
|
||||
/* Timeout has expired. */
|
||||
expired = 1;
|
||||
done = 1;
|
||||
}
|
||||
else if(w == WAIT_OBJECT_0)
|
||||
{
|
||||
} else if (w == WAIT_OBJECT_0) {
|
||||
/* Save the index of the reporting thread and release the mutex.
|
||||
The thread will block until we signal its Empty mutex. */
|
||||
cp->CurrentIndex = cp->SharedIndex;
|
||||
ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
|
||||
|
||||
/* Data are available or a pipe closed. */
|
||||
if(cp->Pipe[cp->CurrentIndex].Closed)
|
||||
{
|
||||
if (cp->Pipe[cp->CurrentIndex].Closed) {
|
||||
/* The pipe closed at the write end. Close the read end and
|
||||
inform the wakeup thread it is done with this process. */
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
|
||||
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0);
|
||||
KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex));
|
||||
--cp->PipesLeft;
|
||||
}
|
||||
else if(data && length)
|
||||
{
|
||||
} else if (data && length) {
|
||||
/* Report this data. */
|
||||
*data = cp->Pipe[cp->CurrentIndex].DataBuffer;
|
||||
*length = cp->Pipe[cp->CurrentIndex].DataLength;
|
||||
switch(cp->CurrentIndex)
|
||||
{
|
||||
switch (cp->CurrentIndex) {
|
||||
case KWSYSPE_PIPE_STDOUT:
|
||||
pipeId = kwsysProcess_Pipe_STDOUT; break;
|
||||
pipeId = kwsysProcess_Pipe_STDOUT;
|
||||
break;
|
||||
case KWSYSPE_PIPE_STDERR:
|
||||
pipeId = kwsysProcess_Pipe_STDERR; break;
|
||||
}
|
||||
done = 1;
|
||||
pipeId = kwsysProcess_Pipe_STDERR;
|
||||
break;
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* A process has terminated. */
|
||||
kwsysProcessDestroy(cp, w-WAIT_OBJECT_0);
|
||||
}
|
||||
kwsysProcessDestroy(cp, w - WAIT_OBJECT_0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the user timeout. */
|
||||
if(userTimeout)
|
||||
{
|
||||
if (userTimeout) {
|
||||
kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
|
||||
kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
|
||||
userStartTime);
|
||||
kwsysProcessTime difference =
|
||||
kwsysProcessTimeSubtract(userEndTime, userStartTime);
|
||||
double d = kwsysProcessTimeToDouble(difference);
|
||||
*userTimeout -= d;
|
||||
if(*userTimeout < 0)
|
||||
{
|
||||
if (*userTimeout < 0) {
|
||||
*userTimeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check what happened. */
|
||||
if(pipeId)
|
||||
{
|
||||
if (pipeId) {
|
||||
/* Data are ready on a pipe. */
|
||||
return pipeId;
|
||||
}
|
||||
else if(expired)
|
||||
{
|
||||
} else if (expired) {
|
||||
/* A timeout has expired. */
|
||||
if(user)
|
||||
{
|
||||
if (user) {
|
||||
/* The user timeout has expired. It has no time left. */
|
||||
return kwsysProcess_Pipe_Timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The process timeout has expired. Kill the child now. */
|
||||
KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n"));
|
||||
kwsysProcess_Kill(cp);
|
||||
cp->TimeoutExpired = 1;
|
||||
cp->Killed = 0;
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The children have terminated and no more data are available. */
|
||||
return kwsysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1418,75 +1296,62 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
|
||||
int pipe;
|
||||
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the process to terminate. Ignore all data. */
|
||||
while((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
|
||||
{
|
||||
if(pipe == kwsysProcess_Pipe_Timeout)
|
||||
{
|
||||
while ((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0) {
|
||||
if (pipe == kwsysProcess_Pipe_Timeout) {
|
||||
/* The user timeout has expired. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KWSYSPE_DEBUG((stderr, "no more data\n"));
|
||||
|
||||
/* When the last pipe closes in WaitForData, the loop terminates
|
||||
without releasing the pipe's thread. Release it now. */
|
||||
if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
|
||||
{
|
||||
if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
|
||||
KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
|
||||
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
|
||||
cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for all pipe threads to reset. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i));
|
||||
WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
|
||||
KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i));
|
||||
WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- It is now safe again to call kwsysProcessCleanup. ----- */
|
||||
/* Close all the pipes. */
|
||||
kwsysProcessCleanup(cp, 0);
|
||||
|
||||
/* Determine the outcome. */
|
||||
if(cp->Killed)
|
||||
{
|
||||
if (cp->Killed) {
|
||||
/* We killed the child. */
|
||||
cp->State = kwsysProcess_State_Killed;
|
||||
}
|
||||
else if(cp->TimeoutExpired)
|
||||
{
|
||||
} else if (cp->TimeoutExpired) {
|
||||
/* The timeout expired. */
|
||||
cp->State = kwsysProcess_State_Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The children exited. Report the outcome of the last process. */
|
||||
cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands-1];
|
||||
if((cp->ExitCode & 0xF0000000) == 0xC0000000)
|
||||
{
|
||||
cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands - 1];
|
||||
if ((cp->ExitCode & 0xF0000000) == 0xC0000000) {
|
||||
/* Child terminated due to exceptional behavior. */
|
||||
cp->State = kwsysProcess_State_Exception;
|
||||
cp->ExitValue = 1;
|
||||
kwsysProcessSetExitException(cp, cp->ExitCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Child exited without exception. */
|
||||
cp->State = kwsysProcess_State_Exited;
|
||||
cp->ExitException = kwsysProcess_Exception_None;
|
||||
cp->ExitValue = cp->ExitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1496,45 +1361,37 @@ void kwsysProcess_Interrupt(kwsysProcess* cp)
|
||||
{
|
||||
int i;
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed) {
|
||||
KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip actually interrupting the child if it has already terminated. */
|
||||
if(cp->Terminated)
|
||||
{
|
||||
if (cp->Terminated) {
|
||||
KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Interrupt the children. */
|
||||
if (cp->CreateProcessGroup)
|
||||
{
|
||||
if(cp->ProcessInformation)
|
||||
{
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
if (cp->CreateProcessGroup) {
|
||||
if (cp->ProcessInformation) {
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
/* Make sure the process handle isn't closed (e.g. from disowning). */
|
||||
if(cp->ProcessInformation[i].hProcess)
|
||||
{
|
||||
if (cp->ProcessInformation[i].hProcess) {
|
||||
/* The user created a process group for this process. The group ID
|
||||
is the process ID for the original process in the group. Note
|
||||
that we have to use Ctrl+Break: Ctrl+C is not allowed for process
|
||||
groups. */
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
|
||||
cp->ProcessInformation[i].dwProcessId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* No process group was created. Kill our own process group... */
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1542,34 +1399,31 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
||||
{
|
||||
int i;
|
||||
/* Make sure we are executing a process. */
|
||||
if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed)
|
||||
{
|
||||
if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
|
||||
cp->Killed) {
|
||||
KWSYSPE_DEBUG((stderr, "kill: child not executing\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the reading threads. */
|
||||
KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n"));
|
||||
kwsysProcessDisablePipeThreads(cp);
|
||||
|
||||
/* Skip actually killing the child if it has already terminated. */
|
||||
if(cp->Terminated)
|
||||
{
|
||||
if (cp->Terminated) {
|
||||
KWSYSPE_DEBUG((stderr, "kill: child already terminated\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill the children. */
|
||||
cp->Killed = 1;
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
|
||||
/* Remove from global list of processes and close handles. */
|
||||
kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
/* We are killing the children and ignoring all data. Do not wait
|
||||
for them to exit. */
|
||||
@@ -1587,14 +1441,13 @@ DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd)
|
||||
kwsysProcess* cp = td->Process;
|
||||
|
||||
/* Wait for a process to be ready. */
|
||||
while((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting))
|
||||
{
|
||||
while ((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting)) {
|
||||
/* Read output from the process for this thread's pipe. */
|
||||
kwsysProcessPipeThreadReadPipe(cp, td);
|
||||
|
||||
/* Signal the main thread we have reset for a new process. */
|
||||
ReleaseSemaphore(td->Reader.Reset, 1, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1607,24 +1460,21 @@ DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd)
|
||||
void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
|
||||
{
|
||||
/* Wait for space in the thread's buffer. */
|
||||
while((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)),
|
||||
WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed))
|
||||
{
|
||||
while ((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)),
|
||||
WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed)) {
|
||||
KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index));
|
||||
|
||||
/* Read data from the pipe. This may block until data are available. */
|
||||
if(!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
|
||||
&td->DataLength, 0))
|
||||
{
|
||||
if(GetLastError() != ERROR_BROKEN_PIPE)
|
||||
{
|
||||
if (!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
|
||||
&td->DataLength, 0)) {
|
||||
if (GetLastError() != ERROR_BROKEN_PIPE) {
|
||||
/* UNEXPECTED failure to read the pipe. */
|
||||
}
|
||||
}
|
||||
|
||||
/* The pipe closed. There are no more data to read. */
|
||||
td->Closed = 1;
|
||||
KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index));
|
||||
}
|
||||
}
|
||||
|
||||
KWSYSPE_DEBUG((stderr, "read %d\n", td->Index));
|
||||
|
||||
@@ -1636,7 +1486,7 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
|
||||
/* Tell the main thread we have something to report. */
|
||||
cp->SharedIndex = td->Index;
|
||||
ReleaseSemaphore(cp->Full, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* We were signalled to exit with our buffer empty. Reset the
|
||||
mutex for a new process. */
|
||||
@@ -1656,14 +1506,13 @@ DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd)
|
||||
kwsysProcess* cp = td->Process;
|
||||
|
||||
/* Wait for a process to be ready. */
|
||||
while((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting))
|
||||
{
|
||||
while ((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting)) {
|
||||
/* Wait for a possible wakeup. */
|
||||
kwsysProcessPipeThreadWakePipe(cp, td);
|
||||
|
||||
/* Signal the main thread we have reset for a new process. */
|
||||
ReleaseSemaphore(td->Waker.Reset, 1, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1683,13 +1532,12 @@ void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td)
|
||||
KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index));
|
||||
|
||||
/* If the pipe is not closed, we need to wake up the reading thread. */
|
||||
if(!td->Closed)
|
||||
{
|
||||
if (!td->Closed) {
|
||||
DWORD dummy;
|
||||
KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index));
|
||||
WriteFile(td->Write, "", 1, &dummy, 0);
|
||||
KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1709,55 +1557,48 @@ int kwsysProcessInitialize(kwsysProcess* cp)
|
||||
strcpy(cp->ExitExceptionString, "No exception");
|
||||
|
||||
/* Allocate process information for each process. */
|
||||
cp->ProcessInformation =
|
||||
(PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) *
|
||||
cp->NumberOfCommands);
|
||||
if(!cp->ProcessInformation)
|
||||
{
|
||||
cp->ProcessInformation = (PROCESS_INFORMATION*)malloc(
|
||||
sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
|
||||
if (!cp->ProcessInformation) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ZeroMemory(cp->ProcessInformation,
|
||||
sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
|
||||
if(cp->CommandExitCodes)
|
||||
{
|
||||
if (cp->CommandExitCodes) {
|
||||
free(cp->CommandExitCodes);
|
||||
}
|
||||
cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD)*cp->NumberOfCommands);
|
||||
if(!cp->CommandExitCodes)
|
||||
{
|
||||
}
|
||||
cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands);
|
||||
if (!cp->CommandExitCodes) {
|
||||
return 0;
|
||||
}
|
||||
ZeroMemory(cp->CommandExitCodes, sizeof(DWORD)*cp->NumberOfCommands);
|
||||
}
|
||||
ZeroMemory(cp->CommandExitCodes, sizeof(DWORD) * cp->NumberOfCommands);
|
||||
|
||||
/* Allocate event wait array. The first event is cp->Full, the rest
|
||||
are the process termination events. */
|
||||
cp->ProcessEvents = (PHANDLE)malloc(sizeof(HANDLE)*(cp->NumberOfCommands+1));
|
||||
if(!cp->ProcessEvents)
|
||||
{
|
||||
cp->ProcessEvents =
|
||||
(PHANDLE)malloc(sizeof(HANDLE) * (cp->NumberOfCommands + 1));
|
||||
if (!cp->ProcessEvents) {
|
||||
return 0;
|
||||
}
|
||||
ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands+1));
|
||||
}
|
||||
ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands + 1));
|
||||
cp->ProcessEvents[0] = cp->Full;
|
||||
cp->ProcessEventsLength = cp->NumberOfCommands+1;
|
||||
cp->ProcessEventsLength = cp->NumberOfCommands + 1;
|
||||
|
||||
/* Allocate space to save the real working directory of this process. */
|
||||
if(cp->WorkingDirectory)
|
||||
{
|
||||
if (cp->WorkingDirectory) {
|
||||
cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0);
|
||||
if(cp->RealWorkingDirectoryLength > 0)
|
||||
{
|
||||
cp->RealWorkingDirectory = malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t));
|
||||
if(!cp->RealWorkingDirectory)
|
||||
{
|
||||
if (cp->RealWorkingDirectoryLength > 0) {
|
||||
cp->RealWorkingDirectory =
|
||||
malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t));
|
||||
if (!cp->RealWorkingDirectory) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < 3; ++i)
|
||||
{
|
||||
cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1770,28 +1611,21 @@ static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
|
||||
DWORD flags;
|
||||
|
||||
/* Check whether the handle is valid for this process. */
|
||||
if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags))
|
||||
{
|
||||
if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags)) {
|
||||
/* Use the handle as-is if it is already inherited. */
|
||||
if (flags & HANDLE_FLAG_INHERIT)
|
||||
{
|
||||
if (flags & HANDLE_FLAG_INHERIT) {
|
||||
*out = in;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create an inherited copy of this handle. */
|
||||
if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS)) {
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return GetLastError();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The given handle is not valid for this process. Some child
|
||||
processes may break if they do not have a valid standard handle,
|
||||
so open NUL to give to the child. */
|
||||
@@ -1799,13 +1633,12 @@ static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
|
||||
ZeroMemory(&sa, sizeof(sa));
|
||||
sa.nLength = (DWORD)sizeof(sa);
|
||||
sa.bInheritHandle = 1;
|
||||
*out = CreateFileW(L"NUL",
|
||||
(isStdIn ? GENERIC_READ :
|
||||
(GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
&sa, OPEN_EXISTING, 0, 0);
|
||||
*out = CreateFileW(
|
||||
L"NUL",
|
||||
(isStdIn ? GENERIC_READ : (GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0);
|
||||
return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1816,54 +1649,49 @@ DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
|
||||
/* Check if we are currently exiting. */
|
||||
if (!kwsysTryEnterCreateProcessSection())
|
||||
{
|
||||
if (!kwsysTryEnterCreateProcessSection()) {
|
||||
/* The Ctrl handler is currently working on exiting our process. Rather
|
||||
than return an error code, which could cause incorrect conclusions to be
|
||||
reached by the caller, we simply hang. (For example, a CMake try_run
|
||||
configure step might cause the project to configure wrong.) */
|
||||
Sleep(INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the child in a suspended state so we can wait until all
|
||||
children have been created before running any one. */
|
||||
creationFlags = CREATE_SUSPENDED;
|
||||
if (cp->CreateProcessGroup)
|
||||
{
|
||||
if (cp->CreateProcessGroup) {
|
||||
creationFlags |= CREATE_NEW_PROCESS_GROUP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create inherited copies of the handles. */
|
||||
(error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
|
||||
si->hStdInput, 1)) ||
|
||||
(error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
|
||||
si->hStdOutput, 0)) ||
|
||||
(error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
|
||||
si->hStdError, 0)) ||
|
||||
/* Create the process. */
|
||||
(!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0,
|
||||
0, &si->StartupInfo, &cp->ProcessInformation[index]) &&
|
||||
(error = GetLastError()));
|
||||
si->hStdInput, 1)) ||
|
||||
(error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
|
||||
si->hStdOutput, 0)) ||
|
||||
(error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
|
||||
si->hStdError, 0)) ||
|
||||
/* Create the process. */
|
||||
(!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0, 0,
|
||||
&si->StartupInfo, &cp->ProcessInformation[index]) &&
|
||||
(error = GetLastError()));
|
||||
|
||||
/* Close the inherited copies of the handles. */
|
||||
if (si->StartupInfo.hStdInput != si->hStdInput)
|
||||
{
|
||||
if (si->StartupInfo.hStdInput != si->hStdInput) {
|
||||
kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
|
||||
}
|
||||
if (si->StartupInfo.hStdOutput != si->hStdOutput)
|
||||
{
|
||||
}
|
||||
if (si->StartupInfo.hStdOutput != si->hStdOutput) {
|
||||
kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
|
||||
}
|
||||
if (si->StartupInfo.hStdError != si->hStdError)
|
||||
{
|
||||
}
|
||||
if (si->StartupInfo.hStdError != si->hStdError) {
|
||||
kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the process to the global list of processes. */
|
||||
if (!error &&
|
||||
!kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
|
||||
cp->ProcessInformation[index].dwProcessId, cp->CreateProcessGroup))
|
||||
{
|
||||
cp->ProcessInformation[index].dwProcessId,
|
||||
cp->CreateProcessGroup)) {
|
||||
/* This failed for some reason. Kill the suspended process. */
|
||||
TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
|
||||
/* And clean up... */
|
||||
@@ -1871,7 +1699,7 @@ DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
|
||||
strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
|
||||
error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason. */
|
||||
}
|
||||
}
|
||||
|
||||
/* If the console Ctrl handler is waiting for us, this will release it... */
|
||||
kwsysLeaveCreateProcessSection();
|
||||
@@ -1885,13 +1713,11 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
|
||||
int index;
|
||||
|
||||
/* Find the process index for the termination event. */
|
||||
for(index=0; index < cp->NumberOfCommands; ++index)
|
||||
{
|
||||
if(cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event])
|
||||
{
|
||||
for (index = 0; index < cp->NumberOfCommands; ++index) {
|
||||
if (cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the exit code of the process. */
|
||||
GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
|
||||
@@ -1905,20 +1731,17 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
|
||||
|
||||
/* Remove the process from the available events. */
|
||||
cp->ProcessEventsLength -= 1;
|
||||
for(i=event; i < cp->ProcessEventsLength; ++i)
|
||||
{
|
||||
cp->ProcessEvents[i] = cp->ProcessEvents[i+1];
|
||||
}
|
||||
for (i = event; i < cp->ProcessEventsLength; ++i) {
|
||||
cp->ProcessEvents[i] = cp->ProcessEvents[i + 1];
|
||||
}
|
||||
|
||||
/* Check if all processes have terminated. */
|
||||
if(cp->ProcessEventsLength == 1)
|
||||
{
|
||||
if (cp->ProcessEventsLength == 1) {
|
||||
cp->Terminated = 1;
|
||||
|
||||
/* Close our copies of the pipe write handles so the pipe threads
|
||||
can detect end-of-data. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
/* TODO: If the child created its own child (our grandchild)
|
||||
which inherited a copy of the pipe write-end then the pipe
|
||||
may not close and we will still need the waker write pipe.
|
||||
@@ -1929,8 +1752,8 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
|
||||
read on posix. */
|
||||
KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i));
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -1939,24 +1762,22 @@ DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
|
||||
HANDLE fout;
|
||||
wchar_t* wname;
|
||||
DWORD error;
|
||||
if(!name)
|
||||
{
|
||||
if (!name) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the existing handle. */
|
||||
kwsysProcessCleanupHandle(phandle);
|
||||
|
||||
/* Create a handle to write a file for the pipe. */
|
||||
wname = kwsysEncoding_DupToWide(name);
|
||||
fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0,
|
||||
CREATE_ALWAYS, 0, 0);
|
||||
fout =
|
||||
CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
|
||||
error = GetLastError();
|
||||
free(wname);
|
||||
if(fout == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (fout == INVALID_HANDLE_VALUE) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign the replacement handle. */
|
||||
*phandle = fout;
|
||||
@@ -1986,14 +1807,13 @@ void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle)
|
||||
/* Close the given handle if it is open. Reset its value to 0. */
|
||||
void kwsysProcessCleanupHandle(PHANDLE h)
|
||||
{
|
||||
if(h && *h && *h != INVALID_HANDLE_VALUE &&
|
||||
*h != GetStdHandle(STD_INPUT_HANDLE) &&
|
||||
*h != GetStdHandle(STD_OUTPUT_HANDLE) &&
|
||||
*h != GetStdHandle(STD_ERROR_HANDLE))
|
||||
{
|
||||
if (h && *h && *h != INVALID_HANDLE_VALUE &&
|
||||
*h != GetStdHandle(STD_INPUT_HANDLE) &&
|
||||
*h != GetStdHandle(STD_OUTPUT_HANDLE) &&
|
||||
*h != GetStdHandle(STD_ERROR_HANDLE)) {
|
||||
CloseHandle(*h);
|
||||
*h = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2003,35 +1823,31 @@ void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
|
||||
{
|
||||
int i;
|
||||
/* If this is an error case, report the error. */
|
||||
if(error)
|
||||
{
|
||||
if (error) {
|
||||
/* Construct an error message if one has not been provided already. */
|
||||
if(cp->ErrorMessage[0] == 0)
|
||||
{
|
||||
if (cp->ErrorMessage[0] == 0) {
|
||||
/* Format the error message. */
|
||||
wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
|
||||
DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0);
|
||||
if(length < 1)
|
||||
{
|
||||
DWORD length = FormatMessageW(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_msg,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE, 0);
|
||||
if (length < 1) {
|
||||
/* FormatMessage failed. Use a default message. */
|
||||
_snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
|
||||
"Process execution failed with error 0x%X. "
|
||||
"FormatMessage failed with error 0x%X",
|
||||
error, GetLastError());
|
||||
}
|
||||
if(!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL))
|
||||
{
|
||||
}
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL)) {
|
||||
/* WideCharToMultiByte failed. Use a default message. */
|
||||
_snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
|
||||
"Process execution failed with error 0x%X. "
|
||||
"WideCharToMultiByte failed with error 0x%X",
|
||||
error, GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove trailing period and newline, if any. */
|
||||
kwsysProcessCleanErrorMessage(cp);
|
||||
@@ -2040,60 +1856,50 @@ void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
|
||||
cp->State = kwsysProcess_State_Error;
|
||||
|
||||
/* Cleanup any processes already started in a suspended state. */
|
||||
if(cp->ProcessInformation)
|
||||
{
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
if(cp->ProcessInformation[i].hProcess)
|
||||
{
|
||||
if (cp->ProcessInformation) {
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
if (cp->ProcessInformation[i].hProcess) {
|
||||
TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
|
||||
WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
|
||||
}
|
||||
}
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < cp->NumberOfCommands; ++i) {
|
||||
/* Remove from global list of processes and close handles. */
|
||||
kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the working directory. */
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
if (cp->RealWorkingDirectory) {
|
||||
SetCurrentDirectoryW(cp->RealWorkingDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
if(cp->ProcessInformation)
|
||||
{
|
||||
if (cp->ProcessInformation) {
|
||||
free(cp->ProcessInformation);
|
||||
cp->ProcessInformation = 0;
|
||||
}
|
||||
if(cp->ProcessEvents)
|
||||
{
|
||||
}
|
||||
if (cp->ProcessEvents) {
|
||||
free(cp->ProcessEvents);
|
||||
cp->ProcessEvents = 0;
|
||||
}
|
||||
if(cp->RealWorkingDirectory)
|
||||
{
|
||||
}
|
||||
if (cp->RealWorkingDirectory) {
|
||||
free(cp->RealWorkingDirectory);
|
||||
cp->RealWorkingDirectory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close each pipe. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
|
||||
kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
|
||||
cp->Pipe[i].Closed = 0;
|
||||
}
|
||||
for(i=0; i < 3; ++i)
|
||||
{
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2101,20 +1907,17 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
|
||||
{
|
||||
/* Remove trailing period and newline, if any. */
|
||||
size_t length = strlen(cp->ErrorMessage);
|
||||
if(cp->ErrorMessage[length-1] == '\n')
|
||||
{
|
||||
cp->ErrorMessage[length-1] = 0;
|
||||
if (cp->ErrorMessage[length - 1] == '\n') {
|
||||
cp->ErrorMessage[length - 1] = 0;
|
||||
--length;
|
||||
if(length > 0 && cp->ErrorMessage[length-1] == '\r')
|
||||
{
|
||||
cp->ErrorMessage[length-1] = 0;
|
||||
if (length > 0 && cp->ErrorMessage[length - 1] == '\r') {
|
||||
cp->ErrorMessage[length - 1] = 0;
|
||||
--length;
|
||||
}
|
||||
}
|
||||
if(length > 0 && cp->ErrorMessage[length-1] == '.')
|
||||
{
|
||||
cp->ErrorMessage[length-1] = 0;
|
||||
}
|
||||
}
|
||||
if (length > 0 && cp->ErrorMessage[length - 1] == '.') {
|
||||
cp->ErrorMessage[length - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2125,29 +1928,27 @@ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
|
||||
{
|
||||
/* The first time this is called, we need to calculate the time at
|
||||
which the child will timeout. */
|
||||
if(cp->Timeout && cp->TimeoutTime.QuadPart < 0)
|
||||
{
|
||||
if (cp->Timeout && cp->TimeoutTime.QuadPart < 0) {
|
||||
kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
|
||||
cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start with process timeout. */
|
||||
*timeoutTime = cp->TimeoutTime;
|
||||
|
||||
/* Check if the user timeout is earlier. */
|
||||
if(userTimeout)
|
||||
{
|
||||
if (userTimeout) {
|
||||
kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
|
||||
kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
|
||||
kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
|
||||
userTimeoutLength);
|
||||
if(timeoutTime->QuadPart < 0 ||
|
||||
kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
|
||||
{
|
||||
kwsysProcessTime userTimeoutLength =
|
||||
kwsysProcessTimeFromDouble(*userTimeout);
|
||||
kwsysProcessTime userTimeoutTime =
|
||||
kwsysProcessTimeAdd(currentTime, userTimeoutLength);
|
||||
if (timeoutTime->QuadPart < 0 ||
|
||||
kwsysProcessTimeLess(userTimeoutTime, *timeoutTime)) {
|
||||
*timeoutTime = userTimeoutTime;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2158,34 +1959,27 @@ int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
|
||||
double* userTimeout,
|
||||
kwsysProcessTime* timeoutLength)
|
||||
{
|
||||
if(timeoutTime->QuadPart < 0)
|
||||
{
|
||||
if (timeoutTime->QuadPart < 0) {
|
||||
/* No timeout time has been requested. */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Calculate the remaining time. */
|
||||
kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
|
||||
*timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime);
|
||||
|
||||
if(timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0)
|
||||
{
|
||||
if (timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0) {
|
||||
/* Caller has explicitly requested a zero timeout. */
|
||||
timeoutLength->QuadPart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(timeoutLength->QuadPart < 0)
|
||||
{
|
||||
if (timeoutLength->QuadPart < 0) {
|
||||
/* Timeout has already expired. */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* There is some time left. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2215,7 +2009,7 @@ double kwsysProcessTimeToDouble(kwsysProcessTime t)
|
||||
kwsysProcessTime kwsysProcessTimeFromDouble(double d)
|
||||
{
|
||||
kwsysProcessTime t;
|
||||
t.QuadPart = (LONGLONG)(d*10000000);
|
||||
t.QuadPart = (LONGLONG)(d * 10000000);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -2226,7 +2020,8 @@ int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2)
|
||||
{
|
||||
kwsysProcessTime out;
|
||||
out.QuadPart = in1.QuadPart + in2.QuadPart;
|
||||
@@ -2234,7 +2029,8 @@ kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
|
||||
kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1,
|
||||
kwsysProcessTime in2)
|
||||
{
|
||||
kwsysProcessTime out;
|
||||
out.QuadPart = in1.QuadPart - in2.QuadPart;
|
||||
@@ -2242,71 +2038,93 @@ kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define KWSYSPE_CASE(type, str) \
|
||||
cp->ExitException = kwsysProcess_Exception_##type; \
|
||||
#define KWSYSPE_CASE(type, str) \
|
||||
cp->ExitException = kwsysProcess_Exception_##type; \
|
||||
strcpy(cp->ExitExceptionString, str)
|
||||
static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
switch (code) {
|
||||
case STATUS_CONTROL_C_EXIT:
|
||||
KWSYSPE_CASE(Interrupt, "User interrupt"); break;
|
||||
KWSYSPE_CASE(Interrupt, "User interrupt");
|
||||
break;
|
||||
|
||||
case STATUS_FLOAT_DENORMAL_OPERAND:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)");
|
||||
break;
|
||||
case STATUS_FLOAT_DIVIDE_BY_ZERO:
|
||||
KWSYSPE_CASE(Numerical, "Divide-by-zero"); break;
|
||||
KWSYSPE_CASE(Numerical, "Divide-by-zero");
|
||||
break;
|
||||
case STATUS_FLOAT_INEXACT_RESULT:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)");
|
||||
break;
|
||||
case STATUS_FLOAT_INVALID_OPERATION:
|
||||
KWSYSPE_CASE(Numerical, "Invalid floating-point operation"); break;
|
||||
KWSYSPE_CASE(Numerical, "Invalid floating-point operation");
|
||||
break;
|
||||
case STATUS_FLOAT_OVERFLOW:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point overflow"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point overflow");
|
||||
break;
|
||||
case STATUS_FLOAT_STACK_CHECK:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point stack check failed"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point stack check failed");
|
||||
break;
|
||||
case STATUS_FLOAT_UNDERFLOW:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point underflow"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point underflow");
|
||||
break;
|
||||
#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)");
|
||||
break;
|
||||
#endif
|
||||
#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)"); break;
|
||||
KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)");
|
||||
break;
|
||||
#endif
|
||||
case STATUS_INTEGER_DIVIDE_BY_ZERO:
|
||||
KWSYSPE_CASE(Numerical, "Integer divide-by-zero"); break;
|
||||
KWSYSPE_CASE(Numerical, "Integer divide-by-zero");
|
||||
break;
|
||||
case STATUS_INTEGER_OVERFLOW:
|
||||
KWSYSPE_CASE(Numerical, "Integer overflow"); break;
|
||||
KWSYSPE_CASE(Numerical, "Integer overflow");
|
||||
break;
|
||||
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
KWSYSPE_CASE(Fault, "Datatype misalignment"); break;
|
||||
KWSYSPE_CASE(Fault, "Datatype misalignment");
|
||||
break;
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
KWSYSPE_CASE(Fault, "Access violation"); break;
|
||||
KWSYSPE_CASE(Fault, "Access violation");
|
||||
break;
|
||||
case STATUS_IN_PAGE_ERROR:
|
||||
KWSYSPE_CASE(Fault, "In-page error"); break;
|
||||
KWSYSPE_CASE(Fault, "In-page error");
|
||||
break;
|
||||
case STATUS_INVALID_HANDLE:
|
||||
KWSYSPE_CASE(Fault, "Invalid hanlde"); break;
|
||||
KWSYSPE_CASE(Fault, "Invalid hanlde");
|
||||
break;
|
||||
case STATUS_NONCONTINUABLE_EXCEPTION:
|
||||
KWSYSPE_CASE(Fault, "Noncontinuable exception"); break;
|
||||
KWSYSPE_CASE(Fault, "Noncontinuable exception");
|
||||
break;
|
||||
case STATUS_INVALID_DISPOSITION:
|
||||
KWSYSPE_CASE(Fault, "Invalid disposition"); break;
|
||||
KWSYSPE_CASE(Fault, "Invalid disposition");
|
||||
break;
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
KWSYSPE_CASE(Fault, "Array bounds exceeded"); break;
|
||||
KWSYSPE_CASE(Fault, "Array bounds exceeded");
|
||||
break;
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
KWSYSPE_CASE(Fault, "Stack overflow"); break;
|
||||
KWSYSPE_CASE(Fault, "Stack overflow");
|
||||
break;
|
||||
|
||||
case STATUS_ILLEGAL_INSTRUCTION:
|
||||
KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
|
||||
KWSYSPE_CASE(Illegal, "Illegal instruction");
|
||||
break;
|
||||
case STATUS_PRIVILEGED_INSTRUCTION:
|
||||
KWSYSPE_CASE(Illegal, "Privileged instruction"); break;
|
||||
KWSYSPE_CASE(Illegal, "Privileged instruction");
|
||||
break;
|
||||
|
||||
case STATUS_NO_MEMORY:
|
||||
default:
|
||||
cp->ExitException = kwsysProcess_Exception_Other;
|
||||
_snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code);
|
||||
_snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE,
|
||||
"Exit code 0x%x\n", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef KWSYSPE_CASE
|
||||
|
||||
@@ -2338,21 +2156,21 @@ typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
|
||||
typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
|
||||
struct _SYSTEM_PROCESS_INFORMATION
|
||||
{
|
||||
ULONG NextEntryDelta;
|
||||
ULONG ThreadCount;
|
||||
ULONG Reserved1[6];
|
||||
LARGE_INTEGER CreateTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
ULONG NextEntryDelta;
|
||||
ULONG ThreadCount;
|
||||
ULONG Reserved1[6];
|
||||
LARGE_INTEGER CreateTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
UNICODE_STRING ProcessName;
|
||||
KPRIORITY BasePriority;
|
||||
ULONG ProcessId;
|
||||
ULONG InheritedFromProcessId;
|
||||
KPRIORITY BasePriority;
|
||||
ULONG ProcessId;
|
||||
ULONG InheritedFromProcessId;
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Toolhelp32 API definitions. */
|
||||
#define TH32CS_SNAPPROCESS 0x00000002
|
||||
#define TH32CS_SNAPPROCESS 0x00000002
|
||||
#if defined(_WIN64)
|
||||
typedef unsigned __int64 ProcessULONG_PTR;
|
||||
#else
|
||||
@@ -2369,19 +2187,18 @@ struct tagPROCESSENTRY32
|
||||
DWORD th32ModuleID;
|
||||
DWORD cntThreads;
|
||||
DWORD th32ParentProcessID;
|
||||
LONG pcPriClassBase;
|
||||
LONG pcPriClassBase;
|
||||
DWORD dwFlags;
|
||||
char szExeFile[MAX_PATH];
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Windows API function types. */
|
||||
typedef HANDLE (WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
|
||||
typedef BOOL (WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef BOOL (WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef NTSTATUS (WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID,
|
||||
ULONG, PULONG);
|
||||
|
||||
typedef HANDLE(WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
|
||||
typedef BOOL(WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef BOOL(WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef NTSTATUS(WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID, ULONG,
|
||||
PULONG);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
|
||||
@@ -2423,97 +2240,88 @@ static kwsysProcess_List* kwsysProcess_List_New(void)
|
||||
kwsysProcess_List* self;
|
||||
|
||||
/* Allocate and initialize the list object. */
|
||||
if(!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List))))
|
||||
{
|
||||
if (!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List)))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memset(self, 0, sizeof(*self));
|
||||
|
||||
/* Select an implementation. */
|
||||
ZeroMemory(&osv, sizeof(osv));
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
# pragma warning (push)
|
||||
# ifdef __INTEL_COMPILER
|
||||
# pragma warning (disable:1478)
|
||||
# else
|
||||
# pragma warning (disable:4996)
|
||||
# endif
|
||||
#pragma warning(push)
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning(disable : 1478)
|
||||
#else
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
#endif
|
||||
GetVersionEx(&osv);
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||
osv.dwMajorVersion < 5)? 1:0;
|
||||
self->NT4 =
|
||||
(osv.dwPlatformId == VER_PLATFORM_WIN32_NT && osv.dwMajorVersion < 5) ? 1
|
||||
: 0;
|
||||
|
||||
/* Initialize the selected implementation. */
|
||||
if(!(self->NT4?
|
||||
kwsysProcess_List__New_NT4(self) :
|
||||
kwsysProcess_List__New_Snapshot(self)))
|
||||
{
|
||||
if (!(self->NT4 ? kwsysProcess_List__New_NT4(self)
|
||||
: kwsysProcess_List__New_Snapshot(self))) {
|
||||
kwsysProcess_List_Delete(self);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update to the current set of processes. */
|
||||
if(!kwsysProcess_List_Update(self))
|
||||
{
|
||||
if (!kwsysProcess_List_Update(self)) {
|
||||
kwsysProcess_List_Delete(self);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void kwsysProcess_List_Delete(kwsysProcess_List* self)
|
||||
{
|
||||
if(self)
|
||||
{
|
||||
if(self->NT4)
|
||||
{
|
||||
if (self) {
|
||||
if (self->NT4) {
|
||||
kwsysProcess_List__Delete_NT4(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
kwsysProcess_List__Delete_Snapshot(self);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List_Update(kwsysProcess_List* self)
|
||||
{
|
||||
return self? (self->NT4?
|
||||
kwsysProcess_List__Update_NT4(self) :
|
||||
kwsysProcess_List__Update_Snapshot(self)) : 0;
|
||||
return self ? (self->NT4 ? kwsysProcess_List__Update_NT4(self)
|
||||
: kwsysProcess_List__Update_Snapshot(self))
|
||||
: 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
|
||||
{
|
||||
return self? (self->NT4?
|
||||
kwsysProcess_List__GetProcessId_NT4(self) :
|
||||
kwsysProcess_List__GetProcessId_Snapshot(self)) : -1;
|
||||
|
||||
return self ? (self->NT4 ? kwsysProcess_List__GetProcessId_NT4(self)
|
||||
: kwsysProcess_List__GetProcessId_Snapshot(self))
|
||||
: -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
|
||||
{
|
||||
return self? (self->NT4?
|
||||
kwsysProcess_List__GetParentId_NT4(self) :
|
||||
kwsysProcess_List__GetParentId_Snapshot(self)) : -1;
|
||||
|
||||
return self ? (self->NT4 ? kwsysProcess_List__GetParentId_NT4(self)
|
||||
: kwsysProcess_List__GetParentId_Snapshot(self))
|
||||
: -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
|
||||
{
|
||||
return (self? (self->NT4?
|
||||
kwsysProcess_List__Next_NT4(self) :
|
||||
kwsysProcess_List__Next_Snapshot(self)) : 0);
|
||||
return (self ? (self->NT4 ? kwsysProcess_List__Next_NT4(self)
|
||||
: kwsysProcess_List__Next_Snapshot(self))
|
||||
: 0);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2524,100 +2332,85 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
|
||||
reference count to the module so we do not need to close the
|
||||
handle. */
|
||||
HMODULE hNT = GetModuleHandleW(L"ntdll.dll");
|
||||
if(hNT)
|
||||
{
|
||||
if (hNT) {
|
||||
/* Get pointers to the needed API functions. */
|
||||
self->P_ZwQuerySystemInformation =
|
||||
((ZwQuerySystemInformationType)
|
||||
GetProcAddress(hNT, "ZwQuerySystemInformation"));
|
||||
}
|
||||
if(!self->P_ZwQuerySystemInformation)
|
||||
{
|
||||
((ZwQuerySystemInformationType)GetProcAddress(
|
||||
hNT, "ZwQuerySystemInformation"));
|
||||
}
|
||||
if (!self->P_ZwQuerySystemInformation) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate an initial process information buffer. */
|
||||
self->BufferSize = 32768;
|
||||
self->Buffer = (char*)malloc(self->BufferSize);
|
||||
return self->Buffer? 1:0;
|
||||
return self->Buffer ? 1 : 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
|
||||
{
|
||||
/* Free the process information buffer. */
|
||||
if(self->Buffer)
|
||||
{
|
||||
if (self->Buffer) {
|
||||
free(self->Buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
|
||||
{
|
||||
self->CurrentInfo = 0;
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
/* Query number 5 is for system process list. */
|
||||
NTSTATUS status =
|
||||
self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
|
||||
if(status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
if (status == STATUS_INFO_LENGTH_MISMATCH) {
|
||||
/* The query requires a bigger buffer. */
|
||||
int newBufferSize = self->BufferSize * 2;
|
||||
char* newBuffer = (char*)malloc(newBufferSize);
|
||||
if(newBuffer)
|
||||
{
|
||||
if (newBuffer) {
|
||||
free(self->Buffer);
|
||||
self->Buffer = newBuffer;
|
||||
self->BufferSize = newBufferSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(status >= 0)
|
||||
{
|
||||
} else if (status >= 0) {
|
||||
/* The query succeeded. Initialize traversal of the process list. */
|
||||
self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The query failed. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
|
||||
{
|
||||
if(self->CurrentInfo)
|
||||
{
|
||||
if(self->CurrentInfo->NextEntryDelta > 0)
|
||||
{
|
||||
self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)
|
||||
((char*)self->CurrentInfo +
|
||||
self->CurrentInfo->NextEntryDelta));
|
||||
if (self->CurrentInfo) {
|
||||
if (self->CurrentInfo->NextEntryDelta > 0) {
|
||||
self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)(
|
||||
(char*)self->CurrentInfo + self->CurrentInfo->NextEntryDelta));
|
||||
return 1;
|
||||
}
|
||||
self->CurrentInfo = 0;
|
||||
}
|
||||
self->CurrentInfo = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
|
||||
{
|
||||
return self->CurrentInfo? self->CurrentInfo->ProcessId : -1;
|
||||
return self->CurrentInfo ? self->CurrentInfo->ProcessId : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
|
||||
{
|
||||
return self->CurrentInfo? self->CurrentInfo->InheritedFromProcessId : -1;
|
||||
return self->CurrentInfo ? self->CurrentInfo->InheritedFromProcessId : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2628,92 +2421,83 @@ static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
|
||||
reference count to the module so we do not need to close the
|
||||
handle. */
|
||||
HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
|
||||
if(hKernel)
|
||||
{
|
||||
if (hKernel) {
|
||||
self->P_CreateToolhelp32Snapshot =
|
||||
((CreateToolhelp32SnapshotType)
|
||||
GetProcAddress(hKernel, "CreateToolhelp32Snapshot"));
|
||||
((CreateToolhelp32SnapshotType)GetProcAddress(
|
||||
hKernel, "CreateToolhelp32Snapshot"));
|
||||
self->P_Process32First =
|
||||
((Process32FirstType)
|
||||
GetProcAddress(hKernel, "Process32First"));
|
||||
((Process32FirstType)GetProcAddress(hKernel, "Process32First"));
|
||||
self->P_Process32Next =
|
||||
((Process32NextType)
|
||||
GetProcAddress(hKernel, "Process32Next"));
|
||||
}
|
||||
return (self->P_CreateToolhelp32Snapshot &&
|
||||
self->P_Process32First &&
|
||||
self->P_Process32Next)? 1:0;
|
||||
((Process32NextType)GetProcAddress(hKernel, "Process32Next"));
|
||||
}
|
||||
return (self->P_CreateToolhelp32Snapshot && self->P_Process32First &&
|
||||
self->P_Process32Next)
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
|
||||
{
|
||||
if(self->Snapshot)
|
||||
{
|
||||
if (self->Snapshot) {
|
||||
CloseHandle(self->Snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
|
||||
{
|
||||
if(self->Snapshot)
|
||||
{
|
||||
if (self->Snapshot) {
|
||||
CloseHandle(self->Snapshot);
|
||||
}
|
||||
if(!(self->Snapshot =
|
||||
self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)))
|
||||
{
|
||||
}
|
||||
if (!(self->Snapshot =
|
||||
self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
|
||||
self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
|
||||
if(!self->P_Process32First(self->Snapshot, &self->CurrentEntry))
|
||||
{
|
||||
if (!self->P_Process32First(self->Snapshot, &self->CurrentEntry)) {
|
||||
CloseHandle(self->Snapshot);
|
||||
self->Snapshot = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
|
||||
{
|
||||
if(self->Snapshot)
|
||||
{
|
||||
if(self->P_Process32Next(self->Snapshot, &self->CurrentEntry))
|
||||
{
|
||||
if (self->Snapshot) {
|
||||
if (self->P_Process32Next(self->Snapshot, &self->CurrentEntry)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
CloseHandle(self->Snapshot);
|
||||
self->Snapshot = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
|
||||
{
|
||||
return self->Snapshot? self->CurrentEntry.th32ProcessID : -1;
|
||||
return self->Snapshot ? self->CurrentEntry.th32ProcessID : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
|
||||
{
|
||||
return self->Snapshot? self->CurrentEntry.th32ParentProcessID : -1;
|
||||
return self->Snapshot ? self->CurrentEntry.th32ParentProcessID : -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void kwsysProcessKill(DWORD pid)
|
||||
{
|
||||
HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
|
||||
if(h)
|
||||
{
|
||||
if (h) {
|
||||
TerminateProcess(h, 255);
|
||||
WaitForSingleObject(h, INFINITE);
|
||||
CloseHandle(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2721,18 +2505,15 @@ static void kwsysProcessKillTree(int pid)
|
||||
{
|
||||
kwsysProcess_List* plist = kwsysProcess_List_New();
|
||||
kwsysProcessKill(pid);
|
||||
if(plist)
|
||||
{
|
||||
do
|
||||
{
|
||||
if(kwsysProcess_List_GetCurrentParentId(plist) == pid)
|
||||
{
|
||||
if (plist) {
|
||||
do {
|
||||
if (kwsysProcess_List_GetCurrentParentId(plist) == pid) {
|
||||
int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
|
||||
kwsysProcessKillTree(ppid);
|
||||
}
|
||||
} while(kwsysProcess_List_NextProcess(plist));
|
||||
}
|
||||
} while (kwsysProcess_List_NextProcess(plist));
|
||||
kwsysProcess_List_Delete(plist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2741,16 +2522,14 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
|
||||
int i;
|
||||
|
||||
/* If data were just reported data, release the pipe's thread. */
|
||||
if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
|
||||
{
|
||||
if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) {
|
||||
KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
|
||||
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
|
||||
cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wakeup all reading threads that are not on closed pipes. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) {
|
||||
/* The wakeup threads will write one byte to the pipe write ends.
|
||||
If there are no data in the pipe then this is enough to wakeup
|
||||
the reading threads. If there are already data in the pipe
|
||||
@@ -2762,16 +2541,14 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
|
||||
thread to call WriteFile. If it blocks, that is okay because
|
||||
it will unblock when we close the read end and break the pipe
|
||||
below. */
|
||||
if(cp->Pipe[i].Read)
|
||||
{
|
||||
if (cp->Pipe[i].Read) {
|
||||
KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i));
|
||||
ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell pipe threads to reset until we run another process. */
|
||||
while(cp->PipesLeft > 0)
|
||||
{
|
||||
while (cp->PipesLeft > 0) {
|
||||
/* The waking threads will cause all reading threads to report.
|
||||
Wait for the next one and save its index. */
|
||||
KWSYSPE_DEBUG((stderr, "waiting for reader\n"));
|
||||
@@ -2788,7 +2565,7 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
|
||||
/* Tell the reading thread we are done with the data. It will
|
||||
reset immediately because the pipe is closed. */
|
||||
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2827,18 +2604,16 @@ static kwsysProcessInstances kwsysProcesses;
|
||||
static int kwsysProcessesInitialize(void)
|
||||
{
|
||||
/* Initialize everything if not done already. */
|
||||
if(!kwsysProcesses.Initialized)
|
||||
{
|
||||
if (!kwsysProcesses.Initialized) {
|
||||
InitializeCriticalSection(&kwsysProcesses.Lock);
|
||||
|
||||
/* Set up console ctrl handler. */
|
||||
if(!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE))
|
||||
{
|
||||
if (!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
kwsysProcesses.Initialized = 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2853,15 +2628,12 @@ static int kwsysTryEnterCreateProcessSection(void)
|
||||
handler are mutually exclusive. */
|
||||
EnterCriticalSection(&kwsysProcesses.Lock);
|
||||
/* Indicate to the caller if they can create a process. */
|
||||
if(kwsysProcesses.Exiting)
|
||||
{
|
||||
if (kwsysProcesses.Exiting) {
|
||||
LeaveCriticalSection(&kwsysProcesses.Lock);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -2880,41 +2652,35 @@ static void kwsysLeaveCreateProcessSection(void)
|
||||
static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
|
||||
int newProcessGroup)
|
||||
{
|
||||
if(!kwsysProcessesInitialize() || !hProcess ||
|
||||
hProcess == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!kwsysProcessesInitialize() || !hProcess ||
|
||||
hProcess == INVALID_HANDLE_VALUE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enter the critical section. */
|
||||
EnterCriticalSection(&kwsysProcesses.Lock);
|
||||
|
||||
/* Make sure there is enough space for the new process handle. */
|
||||
if(kwsysProcesses.Count == kwsysProcesses.Size)
|
||||
{
|
||||
if (kwsysProcesses.Count == kwsysProcesses.Size) {
|
||||
size_t newSize;
|
||||
kwsysProcessInstance *newArray;
|
||||
kwsysProcessInstance* newArray;
|
||||
/* Start with enough space for a small number of process handles
|
||||
and double the size each time more is needed. */
|
||||
newSize = kwsysProcesses.Size? kwsysProcesses.Size*2 : 4;
|
||||
newSize = kwsysProcesses.Size ? kwsysProcesses.Size * 2 : 4;
|
||||
|
||||
/* Try allocating the new block of memory. */
|
||||
if(newArray = (kwsysProcessInstance*)malloc(
|
||||
newSize*sizeof(kwsysProcessInstance)))
|
||||
{
|
||||
if (newArray = (kwsysProcessInstance*)malloc(
|
||||
newSize * sizeof(kwsysProcessInstance))) {
|
||||
/* Copy the old process handles to the new memory. */
|
||||
if(kwsysProcesses.Count > 0)
|
||||
{
|
||||
if (kwsysProcesses.Count > 0) {
|
||||
memcpy(newArray, kwsysProcesses.Processes,
|
||||
kwsysProcesses.Count * sizeof(kwsysProcessInstance));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Failed to allocate memory for the new process handle set. */
|
||||
LeaveCriticalSection(&kwsysProcesses.Lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free original array. */
|
||||
free(kwsysProcesses.Processes);
|
||||
@@ -2922,7 +2688,7 @@ static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
|
||||
/* Update original structure with new allocation. */
|
||||
kwsysProcesses.Size = newSize;
|
||||
kwsysProcesses.Processes = newArray;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the new process information to the set. */
|
||||
kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
|
||||
@@ -2942,38 +2708,32 @@ static void kwsysProcessesRemove(HANDLE hProcess)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!hProcess || hProcess == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!hProcess || hProcess == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection(&kwsysProcesses.Lock);
|
||||
|
||||
/* Find the given process in the set. */
|
||||
for(i=0; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
if(kwsysProcesses.Processes[i].hProcess == hProcess)
|
||||
{
|
||||
for (i = 0; i < kwsysProcesses.Count; ++i) {
|
||||
if (kwsysProcesses.Processes[i].hProcess == hProcess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < kwsysProcesses.Count)
|
||||
{
|
||||
}
|
||||
if (i < kwsysProcesses.Count) {
|
||||
/* Found it! Remove the process from the set. */
|
||||
--kwsysProcesses.Count;
|
||||
for(; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i+1];
|
||||
}
|
||||
for (; i < kwsysProcesses.Count; ++i) {
|
||||
kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i + 1];
|
||||
}
|
||||
|
||||
/* If this was the last process, free the array. */
|
||||
if(kwsysProcesses.Count == 0)
|
||||
{
|
||||
if (kwsysProcesses.Count == 0) {
|
||||
kwsysProcesses.Size = 0;
|
||||
free(kwsysProcesses.Processes);
|
||||
kwsysProcesses.Processes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&kwsysProcesses.Lock);
|
||||
}
|
||||
@@ -2991,25 +2751,21 @@ static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
|
||||
|
||||
/* If some of our processes were created in a new process group, we must
|
||||
manually interrupt them. They won't otherwise receive a Ctrl+C/Break. */
|
||||
for(i=0; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
if(kwsysProcesses.Processes[i].NewProcessGroup)
|
||||
{
|
||||
for (i = 0; i < kwsysProcesses.Count; ++i) {
|
||||
if (kwsysProcesses.Processes[i].NewProcessGroup) {
|
||||
DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
|
||||
if(groupId)
|
||||
{
|
||||
if (groupId) {
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for each child process to exit. This is the key step that prevents
|
||||
us from leaving several orphaned children processes running in the
|
||||
background when the user presses Ctrl+C. */
|
||||
for(i=0; i < kwsysProcesses.Count; ++i)
|
||||
{
|
||||
for (i = 0; i < kwsysProcesses.Count; ++i) {
|
||||
WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Leave critical section. */
|
||||
LeaveCriticalSection(&kwsysProcesses.Lock);
|
||||
@@ -3021,10 +2777,9 @@ static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void kwsysProcess_ResetStartTime(kwsysProcess* cp)
|
||||
{
|
||||
if(!cp)
|
||||
{
|
||||
if (!cp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Reset start time. */
|
||||
cp->StartTime = kwsysProcessTimeGetCurrent();
|
||||
}
|
||||
+786
-816
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
//
|
||||
// Copyright (C) 1991 Texas Instruments Incorporated.
|
||||
//
|
||||
@@ -34,30 +25,29 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "RegularExpression.hxx.in"
|
||||
#include "RegularExpression.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
namespace KWSYS_NAMESPACE {
|
||||
|
||||
// RegularExpression -- Copies the given regular expression.
|
||||
RegularExpression::RegularExpression (const RegularExpression& rxp) {
|
||||
if ( !rxp.program )
|
||||
{
|
||||
RegularExpression::RegularExpression(const RegularExpression& rxp)
|
||||
{
|
||||
if (!rxp.program) {
|
||||
this->program = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
int ind;
|
||||
this->progsize = rxp.progsize; // Copy regular expression size
|
||||
this->program = new char[this->progsize]; // Allocate storage
|
||||
for(ind=this->progsize; ind-- != 0;) // Copy regular expresion
|
||||
this->progsize = rxp.progsize; // Copy regular expression size
|
||||
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
|
||||
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
|
||||
if (rxp.regmust != 0) {
|
||||
char* dum = rxp.program;
|
||||
ind = 0;
|
||||
@@ -67,32 +57,30 @@ RegularExpression::RegularExpression (const RegularExpression& rxp) {
|
||||
}
|
||||
this->regmust = this->program + ind;
|
||||
}
|
||||
this->regstart = rxp.regstart; // Copy starting index
|
||||
this->reganch = rxp.reganch; // Copy remaining private data
|
||||
this->regmlen = rxp.regmlen; // Copy remaining private data
|
||||
this->regstart = rxp.regstart; // Copy starting index
|
||||
this->reganch = rxp.reganch; // Copy remaining private data
|
||||
this->regmlen = rxp.regmlen; // Copy remaining private data
|
||||
}
|
||||
|
||||
// operator= -- Copies the given regular expression.
|
||||
RegularExpression& RegularExpression::operator= (const RegularExpression& rxp)
|
||||
RegularExpression& RegularExpression::operator=(const RegularExpression& rxp)
|
||||
{
|
||||
if(this == &rxp)
|
||||
{
|
||||
if (this == &rxp) {
|
||||
return *this;
|
||||
}
|
||||
if ( !rxp.program )
|
||||
{
|
||||
}
|
||||
if (!rxp.program) {
|
||||
this->program = 0;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
int ind;
|
||||
this->progsize = rxp.progsize; // Copy regular expression size
|
||||
delete [] this->program;
|
||||
this->program = new char[this->progsize]; // Allocate storage
|
||||
for(ind=this->progsize; ind-- != 0;) // Copy regular expresion
|
||||
this->progsize = rxp.progsize; // Copy regular expression size
|
||||
delete[] this->program;
|
||||
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
|
||||
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
|
||||
if (rxp.regmust != 0) {
|
||||
char* dum = rxp.program;
|
||||
ind = 0;
|
||||
@@ -102,37 +90,38 @@ RegularExpression& RegularExpression::operator= (const RegularExpression& rxp)
|
||||
}
|
||||
this->regmust = this->program + ind;
|
||||
}
|
||||
this->regstart = rxp.regstart; // Copy starting index
|
||||
this->reganch = rxp.reganch; // Copy remaining private data
|
||||
this->regmlen = rxp.regmlen; // Copy remaining private data
|
||||
this->regstart = rxp.regstart; // Copy starting index
|
||||
this->reganch = rxp.reganch; // Copy remaining private data
|
||||
this->regmlen = rxp.regmlen; // Copy remaining private data
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// operator== -- Returns true if two regular expressions have the same
|
||||
// compiled program for pattern matching.
|
||||
bool RegularExpression::operator== (const RegularExpression& rxp) const {
|
||||
if (this != &rxp) { // Same address?
|
||||
int ind = this->progsize; // Get regular expression size
|
||||
if (ind != rxp.progsize) // If different size regexp
|
||||
return false; // Return failure
|
||||
while(ind-- != 0) // Else while still characters
|
||||
if(this->program[ind] != rxp.program[ind]) // If regexp are different
|
||||
return false; // Return failure
|
||||
bool RegularExpression::operator==(const RegularExpression& rxp) const
|
||||
{
|
||||
if (this != &rxp) { // Same address?
|
||||
int ind = this->progsize; // Get regular expression size
|
||||
if (ind != rxp.progsize) // If different size regexp
|
||||
return false; // Return failure
|
||||
while (ind-- != 0) // Else while still characters
|
||||
if (this->program[ind] != rxp.program[ind]) // If regexp are different
|
||||
return false; // Return failure
|
||||
}
|
||||
return true; // Else same, return success
|
||||
return true; // Else same, return success
|
||||
}
|
||||
|
||||
|
||||
// deep_equal -- Returns true if have the same compiled regular expressions
|
||||
// and the same start and end pointers.
|
||||
|
||||
bool RegularExpression::deep_equal (const RegularExpression& rxp) const {
|
||||
bool RegularExpression::deep_equal(const RegularExpression& rxp) const
|
||||
{
|
||||
int ind = this->progsize; // Get regular expression size
|
||||
if (ind != rxp.progsize) // If different size regexp
|
||||
return false; // Return failure
|
||||
while(ind-- != 0) // Else while still characters
|
||||
if(this->program[ind] != rxp.program[ind]) // If regexp are different
|
||||
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
|
||||
@@ -204,26 +193,26 @@ bool RegularExpression::deep_equal (const RegularExpression& rxp) const {
|
||||
*/
|
||||
|
||||
// definition number opnd? meaning
|
||||
#define END 0 // no End of program.
|
||||
#define BOL 1 // no Match "" at beginning of line.
|
||||
#define EOL 2 // no Match "" at end of line.
|
||||
#define ANY 3 // no Match any one character.
|
||||
#define ANYOF 4 // str Match any character in this string.
|
||||
#define ANYBUT 5 // str Match any character not in this
|
||||
// string.
|
||||
#define BRANCH 6 // node Match this alternative, or the
|
||||
// next...
|
||||
#define BACK 7 // no Match "", "next" ptr points backward.
|
||||
#define EXACTLY 8 // str Match this string.
|
||||
#define NOTHING 9 // no Match empty string.
|
||||
#define STAR 10 // node Match this (simple) thing 0 or more
|
||||
// times.
|
||||
#define PLUS 11 // node Match this (simple) thing 1 or more
|
||||
// times.
|
||||
#define OPEN 20 // no Mark this point in input as start of
|
||||
// #n.
|
||||
#define END 0 // no End of program.
|
||||
#define BOL 1 // no Match "" at beginning of line.
|
||||
#define EOL 2 // no Match "" at end of line.
|
||||
#define ANY 3 // no Match any one character.
|
||||
#define ANYOF 4 // str Match any character in this string.
|
||||
#define ANYBUT 5 // str Match any character not in this
|
||||
// string.
|
||||
#define BRANCH 6 // node Match this alternative, or the
|
||||
// next...
|
||||
#define BACK 7 // no Match "", "next" ptr points backward.
|
||||
#define EXACTLY 8 // str Match this string.
|
||||
#define NOTHING 9 // no Match empty string.
|
||||
#define STAR 10 // node Match this (simple) thing 0 or more
|
||||
// times.
|
||||
#define PLUS 11 // node Match this (simple) thing 1 or more
|
||||
// times.
|
||||
#define OPEN 20 // no Mark this point in input as start of
|
||||
// #n.
|
||||
// OPEN+1 is number 1, etc.
|
||||
#define CLOSE 30 // no Analogous to OPEN.
|
||||
#define CLOSE 30 // no Analogous to OPEN.
|
||||
|
||||
/*
|
||||
* Opcode notes:
|
||||
@@ -258,32 +247,32 @@ bool RegularExpression::deep_equal (const RegularExpression& rxp) const {
|
||||
* but allows patterns to get big without disasters.
|
||||
*/
|
||||
|
||||
#define OP(p) (*(p))
|
||||
#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
|
||||
#define OPERAND(p) ((p) + 3)
|
||||
#define OP(p) (*(p))
|
||||
#define NEXT(p) (((*((p) + 1) & 0377) << 8) + (*((p) + 2) & 0377))
|
||||
#define OPERAND(p) ((p) + 3)
|
||||
|
||||
const unsigned char MAGIC = 0234;
|
||||
/*
|
||||
* Utility definitions.
|
||||
*/
|
||||
|
||||
#define UCHARAT(p) (reinterpret_cast<const unsigned char*>(p))[0]
|
||||
|
||||
|
||||
#define FAIL(m) { regerror(m); return(0); }
|
||||
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
|
||||
#define META "^$.[()|?+*\\"
|
||||
#define UCHARAT(p) (reinterpret_cast<const unsigned char*>(p))[0]
|
||||
|
||||
#define FAIL(m) \
|
||||
{ \
|
||||
regerror(m); \
|
||||
return (0); \
|
||||
}
|
||||
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
|
||||
#define META "^$.[()|?+*\\"
|
||||
|
||||
/*
|
||||
* Flags to be passed up and down.
|
||||
*/
|
||||
#define HASWIDTH 01 // Known never to match null string.
|
||||
#define SIMPLE 02 // Simple enough to be STAR/PLUS operand.
|
||||
#define SPSTART 04 // Starts with * or +.
|
||||
#define WORST 0 // Worst case.
|
||||
|
||||
|
||||
#define HASWIDTH 01 // Known never to match null string.
|
||||
#define SIMPLE 02 // Simple enough to be STAR/PLUS operand.
|
||||
#define SPSTART 04 // Starts with * or +.
|
||||
#define WORST 0 // Worst case.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -291,15 +280,14 @@ const unsigned char MAGIC = 0234;
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
* Global work variables for compile().
|
||||
*/
|
||||
static const char* regparse; // Input-scan pointer.
|
||||
static int regnpar; // () count.
|
||||
static char regdummy;
|
||||
static char* regcode; // Code-emit pointer; ®dummy = don't.
|
||||
static long regsize; // Code size.
|
||||
static const char* regparse; // Input-scan pointer.
|
||||
static int regnpar; // () count.
|
||||
static char regdummy;
|
||||
static char* regcode; // Code-emit pointer; ®dummy = don't.
|
||||
static long regsize; // Code size.
|
||||
|
||||
/*
|
||||
* Forward declarations for compile()'s friends.
|
||||
@@ -307,24 +295,22 @@ static long regsize; // Code size.
|
||||
// #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);
|
||||
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*);
|
||||
static char* reg(int, int*);
|
||||
static char* regbranch(int*);
|
||||
static char* regpiece(int*);
|
||||
static char* regatom(int*);
|
||||
static char* regnode(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 ();
|
||||
static int strcspn();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* We can't allocate space until we know how big the compiled form will be,
|
||||
* but we can't compile it (and thus know how big it is) until we've got a
|
||||
@@ -339,101 +325,100 @@ static int strcspn ();
|
||||
* of the structure of the compiled regexp.
|
||||
*/
|
||||
|
||||
|
||||
// compile -- compile a regular expression into internal code
|
||||
// for later pattern matching.
|
||||
|
||||
bool RegularExpression::compile (const char* exp) {
|
||||
const char* scan;
|
||||
const char* longest;
|
||||
size_t len;
|
||||
int flags;
|
||||
bool RegularExpression::compile(const char* exp)
|
||||
{
|
||||
const char* scan;
|
||||
const char* longest;
|
||||
size_t len;
|
||||
int flags;
|
||||
|
||||
if (exp == 0) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(No_Expr),
|
||||
printf ("RegularExpression::compile(): No expression supplied.\n");
|
||||
return false;
|
||||
}
|
||||
if (exp == 0) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(No_Expr),
|
||||
printf("RegularExpression::compile(): No expression supplied.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// First pass: determine size, legality.
|
||||
regparse = exp;
|
||||
regnpar = 1;
|
||||
regsize = 0L;
|
||||
regcode = ®dummy;
|
||||
regc(static_cast<char>(MAGIC));
|
||||
if(!reg(0, &flags))
|
||||
{
|
||||
printf ("RegularExpression::compile(): Error in compile.\n");
|
||||
return false;
|
||||
}
|
||||
this->startp[0] = this->endp[0] = this->searchstring = 0;
|
||||
// First pass: determine size, legality.
|
||||
regparse = exp;
|
||||
regnpar = 1;
|
||||
regsize = 0L;
|
||||
regcode = ®dummy;
|
||||
regc(static_cast<char>(MAGIC));
|
||||
if (!reg(0, &flags)) {
|
||||
printf("RegularExpression::compile(): Error in compile.\n");
|
||||
return false;
|
||||
}
|
||||
this->startp[0] = this->endp[0] = this->searchstring = 0;
|
||||
|
||||
// Small enough for pointer-storage convention?
|
||||
if (regsize >= 32767L) { // Probably could be 65535L.
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big),
|
||||
printf ("RegularExpression::compile(): Expression too big.\n");
|
||||
return false;
|
||||
}
|
||||
// Small enough for pointer-storage convention?
|
||||
if (regsize >= 32767L) { // Probably could be 65535L.
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big),
|
||||
printf("RegularExpression::compile(): Expression too big.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate space.
|
||||
//#ifndef _WIN32
|
||||
if (this->program != 0) delete [] this->program;
|
||||
//#endif
|
||||
this->program = new char[regsize];
|
||||
this->progsize = static_cast<int>(regsize);
|
||||
// Allocate space.
|
||||
//#ifndef _WIN32
|
||||
if (this->program != 0)
|
||||
delete[] this->program;
|
||||
//#endif
|
||||
this->program = new char[regsize];
|
||||
this->progsize = static_cast<int>(regsize);
|
||||
|
||||
if (this->program == 0) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
|
||||
printf ("RegularExpression::compile(): Out of memory.\n");
|
||||
return false;
|
||||
}
|
||||
if (this->program == 0) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
|
||||
printf("RegularExpression::compile(): Out of memory.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Second pass: emit code.
|
||||
regparse = exp;
|
||||
regnpar = 1;
|
||||
regcode = this->program;
|
||||
regc(static_cast<char>(MAGIC));
|
||||
reg(0, &flags);
|
||||
// Second pass: emit code.
|
||||
regparse = exp;
|
||||
regnpar = 1;
|
||||
regcode = this->program;
|
||||
regc(static_cast<char>(MAGIC));
|
||||
reg(0, &flags);
|
||||
|
||||
// Dig out information for optimizations.
|
||||
this->regstart = '\0'; // Worst-case defaults.
|
||||
this->reganch = 0;
|
||||
this->regmust = 0;
|
||||
this->regmlen = 0;
|
||||
scan = this->program + 1; // First BRANCH.
|
||||
if (OP(regnext(scan)) == END) { // Only one top-level choice.
|
||||
scan = OPERAND(scan);
|
||||
// Dig out information for optimizations.
|
||||
this->regstart = '\0'; // Worst-case defaults.
|
||||
this->reganch = 0;
|
||||
this->regmust = 0;
|
||||
this->regmlen = 0;
|
||||
scan = this->program + 1; // First BRANCH.
|
||||
if (OP(regnext(scan)) == END) { // Only one top-level choice.
|
||||
scan = OPERAND(scan);
|
||||
|
||||
// Starting-point info.
|
||||
if (OP(scan) == EXACTLY)
|
||||
this->regstart = *OPERAND(scan);
|
||||
else if (OP(scan) == BOL)
|
||||
this->reganch++;
|
||||
// Starting-point info.
|
||||
if (OP(scan) == EXACTLY)
|
||||
this->regstart = *OPERAND(scan);
|
||||
else if (OP(scan) == BOL)
|
||||
this->reganch++;
|
||||
|
||||
//
|
||||
// If there's something expensive in the r.e., find the longest
|
||||
// literal string that must appear and make it the regmust. Resolve
|
||||
// ties in favor of later strings, since the regstart check works
|
||||
// with the beginning of the r.e. and avoiding duplication
|
||||
// strengthens checking. Not a strong reason, but sufficient in the
|
||||
// absence of others.
|
||||
//
|
||||
if (flags & SPSTART) {
|
||||
longest = 0;
|
||||
len = 0;
|
||||
for (; scan != 0; scan = regnext(scan))
|
||||
if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
|
||||
longest = OPERAND(scan);
|
||||
len = strlen(OPERAND(scan));
|
||||
}
|
||||
this->regmust = longest;
|
||||
this->regmlen = len;
|
||||
//
|
||||
// If there's something expensive in the r.e., find the longest
|
||||
// literal string that must appear and make it the regmust. Resolve
|
||||
// ties in favor of later strings, since the regstart check works
|
||||
// with the beginning of the r.e. and avoiding duplication
|
||||
// strengthens checking. Not a strong reason, but sufficient in the
|
||||
// absence of others.
|
||||
//
|
||||
if (flags & SPSTART) {
|
||||
longest = 0;
|
||||
len = 0;
|
||||
for (; scan != 0; scan = regnext(scan))
|
||||
if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
|
||||
longest = OPERAND(scan);
|
||||
len = strlen(OPERAND(scan));
|
||||
}
|
||||
this->regmust = longest;
|
||||
this->regmlen = len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- reg - regular expression, i.e. main body or parenthesized thing
|
||||
*
|
||||
@@ -443,115 +428,112 @@ 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* ret;
|
||||
char* br;
|
||||
char* ender;
|
||||
int parno =0;
|
||||
int flags;
|
||||
static char* reg(int paren, int* flagp)
|
||||
{
|
||||
char* ret;
|
||||
char* br;
|
||||
char* ender;
|
||||
int parno = 0;
|
||||
int flags;
|
||||
|
||||
*flagp = HASWIDTH; // Tentatively.
|
||||
*flagp = HASWIDTH; // Tentatively.
|
||||
|
||||
// Make an OPEN node, if parenthesized.
|
||||
if (paren) {
|
||||
if (regnpar >= RegularExpression::NSUBEXP) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
|
||||
printf ("RegularExpression::compile(): Too many parentheses.\n");
|
||||
return 0;
|
||||
}
|
||||
parno = regnpar;
|
||||
regnpar++;
|
||||
ret = regnode(static_cast<char>(OPEN + parno));
|
||||
// Make an OPEN node, if parenthesized.
|
||||
if (paren) {
|
||||
if (regnpar >= RegularExpression::NSUBEXP) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
|
||||
printf("RegularExpression::compile(): Too many parentheses.\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
parno = regnpar;
|
||||
regnpar++;
|
||||
ret = regnode(static_cast<char>(OPEN + parno));
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
// Pick up the branches, linking them together.
|
||||
// Pick up the branches, linking them together.
|
||||
br = regbranch(&flags);
|
||||
if (br == 0)
|
||||
return (0);
|
||||
if (ret != 0)
|
||||
regtail(ret, br); // OPEN -> first.
|
||||
else
|
||||
ret = br;
|
||||
if (!(flags & HASWIDTH))
|
||||
*flagp &= ~HASWIDTH;
|
||||
*flagp |= flags & SPSTART;
|
||||
while (*regparse == '|') {
|
||||
regparse++;
|
||||
br = regbranch(&flags);
|
||||
if (br == 0)
|
||||
return (0);
|
||||
if (ret != 0)
|
||||
regtail(ret, br); // OPEN -> first.
|
||||
else
|
||||
ret = br;
|
||||
return (0);
|
||||
regtail(ret, br); // BRANCH -> BRANCH.
|
||||
if (!(flags & HASWIDTH))
|
||||
*flagp &= ~HASWIDTH;
|
||||
*flagp &= ~HASWIDTH;
|
||||
*flagp |= flags & SPSTART;
|
||||
while (*regparse == '|') {
|
||||
regparse++;
|
||||
br = regbranch(&flags);
|
||||
if (br == 0)
|
||||
return (0);
|
||||
regtail(ret, br); // BRANCH -> BRANCH.
|
||||
if (!(flags & HASWIDTH))
|
||||
*flagp &= ~HASWIDTH;
|
||||
*flagp |= flags & SPSTART;
|
||||
}
|
||||
}
|
||||
|
||||
// Make a closing node, and hook it on the end.
|
||||
ender = regnode(static_cast<char>((paren) ? CLOSE + parno : END));
|
||||
regtail(ret, ender);
|
||||
// Make a closing node, and hook it on the end.
|
||||
ender = regnode(static_cast<char>((paren) ? CLOSE + parno : END));
|
||||
regtail(ret, ender);
|
||||
|
||||
// Hook the tails of the branches to the closing node.
|
||||
for (br = ret; br != 0; br = regnext(br))
|
||||
regoptail(br, ender);
|
||||
// Hook the tails of the branches to the closing node.
|
||||
for (br = ret; br != 0; br = regnext(br))
|
||||
regoptail(br, ender);
|
||||
|
||||
// Check for proper termination.
|
||||
if (paren && *regparse++ != ')') {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
|
||||
printf ("RegularExpression::compile(): Unmatched parentheses.\n");
|
||||
return 0;
|
||||
// Check for proper termination.
|
||||
if (paren && *regparse++ != ')') {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
|
||||
printf("RegularExpression::compile(): Unmatched parentheses.\n");
|
||||
return 0;
|
||||
} else if (!paren && *regparse != '\0') {
|
||||
if (*regparse == ')') {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
|
||||
printf("RegularExpression::compile(): Unmatched parentheses.\n");
|
||||
return 0;
|
||||
} else {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf("RegularExpression::compile(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
else if (!paren && *regparse != '\0') {
|
||||
if (*regparse == ')') {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
|
||||
printf ("RegularExpression::compile(): Unmatched parentheses.\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::compile(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
// NOTREACHED
|
||||
}
|
||||
return (ret);
|
||||
// NOTREACHED
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regbranch - one alternative of an | operator
|
||||
*
|
||||
* Implements the concatenation operator.
|
||||
*/
|
||||
static char* regbranch (int *flagp) {
|
||||
char* ret;
|
||||
char* chain;
|
||||
char* latest;
|
||||
int flags;
|
||||
static char* regbranch(int* flagp)
|
||||
{
|
||||
char* ret;
|
||||
char* chain;
|
||||
char* latest;
|
||||
int flags;
|
||||
|
||||
*flagp = WORST; // Tentatively.
|
||||
*flagp = WORST; // Tentatively.
|
||||
|
||||
ret = regnode(BRANCH);
|
||||
chain = 0;
|
||||
while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
|
||||
latest = regpiece(&flags);
|
||||
if (latest == 0)
|
||||
return (0);
|
||||
*flagp |= flags & HASWIDTH;
|
||||
if (chain == 0) // First piece.
|
||||
*flagp |= flags & SPSTART;
|
||||
else
|
||||
regtail(chain, latest);
|
||||
chain = latest;
|
||||
}
|
||||
if (chain == 0) // Loop ran zero times.
|
||||
regnode(NOTHING);
|
||||
ret = regnode(BRANCH);
|
||||
chain = 0;
|
||||
while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
|
||||
latest = regpiece(&flags);
|
||||
if (latest == 0)
|
||||
return (0);
|
||||
*flagp |= flags & HASWIDTH;
|
||||
if (chain == 0) // First piece.
|
||||
*flagp |= flags & SPSTART;
|
||||
else
|
||||
regtail(chain, latest);
|
||||
chain = latest;
|
||||
}
|
||||
if (chain == 0) // Loop ran zero times.
|
||||
regnode(NOTHING);
|
||||
|
||||
return (ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regpiece - something followed by possible [*+?]
|
||||
*
|
||||
@@ -561,66 +543,64 @@ 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* ret;
|
||||
char op;
|
||||
char* next;
|
||||
int flags;
|
||||
static char* regpiece(int* flagp)
|
||||
{
|
||||
char* ret;
|
||||
char op;
|
||||
char* next;
|
||||
int flags;
|
||||
|
||||
ret = regatom(&flags);
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
ret = regatom(&flags);
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
|
||||
op = *regparse;
|
||||
if (!ISMULT(op)) {
|
||||
*flagp = flags;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
if (!(flags & HASWIDTH) && op != '?') {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Empty_Operand),
|
||||
printf ("RegularExpression::compile() : *+ operand could be empty.\n");
|
||||
return 0;
|
||||
}
|
||||
*flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
|
||||
|
||||
if (op == '*' && (flags & SIMPLE))
|
||||
reginsert(STAR, ret);
|
||||
else if (op == '*') {
|
||||
// Emit x* as (x&|), where & means "self".
|
||||
reginsert(BRANCH, ret); // Either x
|
||||
regoptail(ret, regnode(BACK)); // and loop
|
||||
regoptail(ret, ret); // back
|
||||
regtail(ret, regnode(BRANCH)); // or
|
||||
regtail(ret, regnode(NOTHING)); // null.
|
||||
}
|
||||
else if (op == '+' && (flags & SIMPLE))
|
||||
reginsert(PLUS, ret);
|
||||
else if (op == '+') {
|
||||
// Emit x+ as x(&|), where & means "self".
|
||||
next = regnode(BRANCH); // Either
|
||||
regtail(ret, next);
|
||||
regtail(regnode(BACK), ret); // loop back
|
||||
regtail(next, regnode(BRANCH)); // or
|
||||
regtail(ret, regnode(NOTHING)); // null.
|
||||
}
|
||||
else if (op == '?') {
|
||||
// Emit x? as (x|)
|
||||
reginsert(BRANCH, ret); // Either x
|
||||
regtail(ret, regnode(BRANCH)); // or
|
||||
next = regnode(NOTHING);// null.
|
||||
regtail(ret, next);
|
||||
regoptail(ret, next);
|
||||
}
|
||||
regparse++;
|
||||
if (ISMULT(*regparse)) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Nested_Operand),
|
||||
printf ("RegularExpression::compile(): Nested *?+.\n");
|
||||
return 0;
|
||||
}
|
||||
op = *regparse;
|
||||
if (!ISMULT(op)) {
|
||||
*flagp = flags;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & HASWIDTH) && op != '?') {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Empty_Operand),
|
||||
printf("RegularExpression::compile() : *+ operand could be empty.\n");
|
||||
return 0;
|
||||
}
|
||||
*flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
|
||||
|
||||
if (op == '*' && (flags & SIMPLE))
|
||||
reginsert(STAR, ret);
|
||||
else if (op == '*') {
|
||||
// Emit x* as (x&|), where & means "self".
|
||||
reginsert(BRANCH, ret); // Either x
|
||||
regoptail(ret, regnode(BACK)); // and loop
|
||||
regoptail(ret, ret); // back
|
||||
regtail(ret, regnode(BRANCH)); // or
|
||||
regtail(ret, regnode(NOTHING)); // null.
|
||||
} else if (op == '+' && (flags & SIMPLE))
|
||||
reginsert(PLUS, ret);
|
||||
else if (op == '+') {
|
||||
// Emit x+ as x(&|), where & means "self".
|
||||
next = regnode(BRANCH); // Either
|
||||
regtail(ret, next);
|
||||
regtail(regnode(BACK), ret); // loop back
|
||||
regtail(next, regnode(BRANCH)); // or
|
||||
regtail(ret, regnode(NOTHING)); // null.
|
||||
} else if (op == '?') {
|
||||
// Emit x? as (x|)
|
||||
reginsert(BRANCH, ret); // Either x
|
||||
regtail(ret, regnode(BRANCH)); // or
|
||||
next = regnode(NOTHING); // null.
|
||||
regtail(ret, next);
|
||||
regoptail(ret, next);
|
||||
}
|
||||
regparse++;
|
||||
if (ISMULT(*regparse)) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Nested_Operand),
|
||||
printf("RegularExpression::compile(): Nested *?+.\n");
|
||||
return 0;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
- regatom - the lowest level
|
||||
@@ -630,349 +610,340 @@ 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* ret;
|
||||
int flags;
|
||||
static char* regatom(int* flagp)
|
||||
{
|
||||
char* ret;
|
||||
int flags;
|
||||
|
||||
*flagp = WORST; // Tentatively.
|
||||
*flagp = WORST; // Tentatively.
|
||||
|
||||
switch (*regparse++) {
|
||||
case '^':
|
||||
ret = regnode(BOL);
|
||||
break;
|
||||
case '$':
|
||||
ret = regnode(EOL);
|
||||
break;
|
||||
case '.':
|
||||
ret = regnode(ANY);
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
break;
|
||||
case '[':{
|
||||
int rxpclass;
|
||||
int rxpclassend;
|
||||
switch (*regparse++) {
|
||||
case '^':
|
||||
ret = regnode(BOL);
|
||||
break;
|
||||
case '$':
|
||||
ret = regnode(EOL);
|
||||
break;
|
||||
case '.':
|
||||
ret = regnode(ANY);
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
break;
|
||||
case '[': {
|
||||
int rxpclass;
|
||||
int rxpclassend;
|
||||
|
||||
if (*regparse == '^') { // Complement of range.
|
||||
ret = regnode(ANYBUT);
|
||||
regparse++;
|
||||
}
|
||||
else
|
||||
ret = regnode(ANYOF);
|
||||
if (*regparse == ']' || *regparse == '-')
|
||||
regc(*regparse++);
|
||||
while (*regparse != '\0' && *regparse != ']') {
|
||||
if (*regparse == '-') {
|
||||
regparse++;
|
||||
if (*regparse == ']' || *regparse == '\0')
|
||||
regc('-');
|
||||
else {
|
||||
rxpclass = UCHARAT(regparse - 2) + 1;
|
||||
rxpclassend = UCHARAT(regparse);
|
||||
if (rxpclass > rxpclassend + 1) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Invalid_Range),
|
||||
printf ("RegularExpression::compile(): Invalid range in [].\n");
|
||||
return 0;
|
||||
}
|
||||
for (; rxpclass <= rxpclassend; rxpclass++)
|
||||
regc(static_cast<char>(rxpclass));
|
||||
regparse++;
|
||||
}
|
||||
}
|
||||
else
|
||||
regc(*regparse++);
|
||||
}
|
||||
regc('\0');
|
||||
if (*regparse != ']') {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket),
|
||||
printf ("RegularExpression::compile(): Unmatched [].\n");
|
||||
return 0;
|
||||
}
|
||||
regparse++;
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
if (*regparse == '^') { // Complement of range.
|
||||
ret = regnode(ANYBUT);
|
||||
regparse++;
|
||||
} else
|
||||
ret = regnode(ANYOF);
|
||||
if (*regparse == ']' || *regparse == '-')
|
||||
regc(*regparse++);
|
||||
while (*regparse != '\0' && *regparse != ']') {
|
||||
if (*regparse == '-') {
|
||||
regparse++;
|
||||
if (*regparse == ']' || *regparse == '\0')
|
||||
regc('-');
|
||||
else {
|
||||
rxpclass = UCHARAT(regparse - 2) + 1;
|
||||
rxpclassend = UCHARAT(regparse);
|
||||
if (rxpclass > rxpclassend + 1) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Invalid_Range),
|
||||
printf("RegularExpression::compile(): Invalid range in [].\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
ret = reg(1, &flags);
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
*flagp |= flags & (HASWIDTH | SPSTART);
|
||||
break;
|
||||
case '\0':
|
||||
case '|':
|
||||
case ')':
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::compile(): Internal error.\n"); // Never here
|
||||
return 0;
|
||||
case '?':
|
||||
case '+':
|
||||
case '*':
|
||||
//RAISE Error, SYM(RegularExpression), SYM(No_Operand),
|
||||
printf ("RegularExpression::compile(): ?+* follows nothing.\n");
|
||||
return 0;
|
||||
case '\\':
|
||||
if (*regparse == '\0') {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash),
|
||||
printf ("RegularExpression::compile(): Trailing backslash.\n");
|
||||
return 0;
|
||||
}
|
||||
ret = regnode(EXACTLY);
|
||||
regc(*regparse++);
|
||||
regc('\0');
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
break;
|
||||
default:{
|
||||
int len;
|
||||
char ender;
|
||||
for (; rxpclass <= rxpclassend; rxpclass++)
|
||||
regc(static_cast<char>(rxpclass));
|
||||
regparse++;
|
||||
}
|
||||
} else
|
||||
regc(*regparse++);
|
||||
}
|
||||
regc('\0');
|
||||
if (*regparse != ']') {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket),
|
||||
printf("RegularExpression::compile(): Unmatched [].\n");
|
||||
return 0;
|
||||
}
|
||||
regparse++;
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
} break;
|
||||
case '(':
|
||||
ret = reg(1, &flags);
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
*flagp |= flags & (HASWIDTH | SPSTART);
|
||||
break;
|
||||
case '\0':
|
||||
case '|':
|
||||
case ')':
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf("RegularExpression::compile(): Internal error.\n"); // Never here
|
||||
return 0;
|
||||
case '?':
|
||||
case '+':
|
||||
case '*':
|
||||
// RAISE Error, SYM(RegularExpression), SYM(No_Operand),
|
||||
printf("RegularExpression::compile(): ?+* follows nothing.\n");
|
||||
return 0;
|
||||
case '\\':
|
||||
if (*regparse == '\0') {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash),
|
||||
printf("RegularExpression::compile(): Trailing backslash.\n");
|
||||
return 0;
|
||||
}
|
||||
ret = regnode(EXACTLY);
|
||||
regc(*regparse++);
|
||||
regc('\0');
|
||||
*flagp |= HASWIDTH | SIMPLE;
|
||||
break;
|
||||
default: {
|
||||
int len;
|
||||
char ender;
|
||||
|
||||
regparse--;
|
||||
len = int(strcspn(regparse, META));
|
||||
if (len <= 0) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::compile(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
ender = *(regparse + len);
|
||||
if (len > 1 && ISMULT(ender))
|
||||
len--; // Back off clear of ?+* operand.
|
||||
*flagp |= HASWIDTH;
|
||||
if (len == 1)
|
||||
*flagp |= SIMPLE;
|
||||
ret = regnode(EXACTLY);
|
||||
while (len > 0) {
|
||||
regc(*regparse++);
|
||||
len--;
|
||||
}
|
||||
regc('\0');
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
regparse--;
|
||||
len = int(strcspn(regparse, META));
|
||||
if (len <= 0) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf("RegularExpression::compile(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
ender = *(regparse + len);
|
||||
if (len > 1 && ISMULT(ender))
|
||||
len--; // Back off clear of ?+* operand.
|
||||
*flagp |= HASWIDTH;
|
||||
if (len == 1)
|
||||
*flagp |= SIMPLE;
|
||||
ret = regnode(EXACTLY);
|
||||
while (len > 0) {
|
||||
regc(*regparse++);
|
||||
len--;
|
||||
}
|
||||
regc('\0');
|
||||
} break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regnode - emit a node
|
||||
Location.
|
||||
*/
|
||||
static char* regnode (char op) {
|
||||
char* ret;
|
||||
char* ptr;
|
||||
|
||||
ret = regcode;
|
||||
if (ret == ®dummy) {
|
||||
regsize += 3;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ptr = ret;
|
||||
*ptr++ = op;
|
||||
*ptr++ = '\0'; // Null "next" pointer.
|
||||
*ptr++ = '\0';
|
||||
regcode = ptr;
|
||||
static char* regnode(char op)
|
||||
{
|
||||
char* ret;
|
||||
char* ptr;
|
||||
|
||||
ret = regcode;
|
||||
if (ret == ®dummy) {
|
||||
regsize += 3;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
ptr = ret;
|
||||
*ptr++ = op;
|
||||
*ptr++ = '\0'; // Null "next" pointer.
|
||||
*ptr++ = '\0';
|
||||
regcode = ptr;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
- regc - emit (if appropriate) a byte of code
|
||||
*/
|
||||
static void regc (char b) {
|
||||
if (regcode != ®dummy)
|
||||
*regcode++ = b;
|
||||
else
|
||||
regsize++;
|
||||
static void regc(char b)
|
||||
{
|
||||
if (regcode != ®dummy)
|
||||
*regcode++ = b;
|
||||
else
|
||||
regsize++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- reginsert - insert an operator in front of already-emitted operand
|
||||
*
|
||||
* Means relocating the operand.
|
||||
*/
|
||||
static void reginsert (char op, char* opnd) {
|
||||
char* src;
|
||||
char* dst;
|
||||
char* place;
|
||||
static void reginsert(char op, char* opnd)
|
||||
{
|
||||
char* src;
|
||||
char* dst;
|
||||
char* place;
|
||||
|
||||
if (regcode == ®dummy) {
|
||||
regsize += 3;
|
||||
return;
|
||||
}
|
||||
if (regcode == ®dummy) {
|
||||
regsize += 3;
|
||||
return;
|
||||
}
|
||||
|
||||
src = regcode;
|
||||
regcode += 3;
|
||||
dst = regcode;
|
||||
while (src > opnd)
|
||||
*--dst = *--src;
|
||||
src = regcode;
|
||||
regcode += 3;
|
||||
dst = regcode;
|
||||
while (src > opnd)
|
||||
*--dst = *--src;
|
||||
|
||||
place = opnd; // Op node, where operand used to be.
|
||||
*place++ = op;
|
||||
*place++ = '\0';
|
||||
*place = '\0';
|
||||
place = opnd; // Op node, where operand used to be.
|
||||
*place++ = op;
|
||||
*place++ = '\0';
|
||||
*place = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regtail - set the next-pointer at the end of a node chain
|
||||
*/
|
||||
static void regtail (char* p, const char* val) {
|
||||
char* scan;
|
||||
char* temp;
|
||||
int offset;
|
||||
static void regtail(char* p, const char* val)
|
||||
{
|
||||
char* scan;
|
||||
char* temp;
|
||||
int offset;
|
||||
|
||||
if (p == ®dummy)
|
||||
return;
|
||||
if (p == ®dummy)
|
||||
return;
|
||||
|
||||
// Find last node.
|
||||
scan = p;
|
||||
for (;;) {
|
||||
temp = regnext(scan);
|
||||
if (temp == 0)
|
||||
break;
|
||||
scan = temp;
|
||||
}
|
||||
// Find last node.
|
||||
scan = p;
|
||||
for (;;) {
|
||||
temp = regnext(scan);
|
||||
if (temp == 0)
|
||||
break;
|
||||
scan = temp;
|
||||
}
|
||||
|
||||
if (OP(scan) == BACK)
|
||||
offset = int(scan - val);
|
||||
else
|
||||
offset = int(val - scan);
|
||||
*(scan + 1) = static_cast<char>((offset >> 8) & 0377);
|
||||
*(scan + 2) = static_cast<char>(offset & 0377);
|
||||
if (OP(scan) == BACK)
|
||||
offset = int(scan - val);
|
||||
else
|
||||
offset = int(val - scan);
|
||||
*(scan + 1) = static_cast<char>((offset >> 8) & 0377);
|
||||
*(scan + 2) = static_cast<char>(offset & 0377);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regoptail - regtail on operand of first argument; nop if operandless
|
||||
*/
|
||||
static void regoptail (char* p, const char* val) {
|
||||
// "Operandless" and "op != BRANCH" are synonymous in practice.
|
||||
if (p == 0 || p == ®dummy || OP(p) != BRANCH)
|
||||
return;
|
||||
regtail(OPERAND(p), val);
|
||||
static void regoptail(char* p, const char* val)
|
||||
{
|
||||
// "Operandless" and "op != BRANCH" are synonymous in practice.
|
||||
if (p == 0 || p == ®dummy || OP(p) != BRANCH)
|
||||
return;
|
||||
regtail(OPERAND(p), val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// find and friends
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
* Global work variables for 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.
|
||||
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.
|
||||
|
||||
/*
|
||||
* Forwards.
|
||||
*/
|
||||
static int regtry (const char*, const char* *,
|
||||
const char* *, const char*);
|
||||
static int regmatch (const char*);
|
||||
static int regrepeat (const char*);
|
||||
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 ();
|
||||
int regnarrate = 0;
|
||||
void regdump();
|
||||
static char* regprop();
|
||||
#endif
|
||||
|
||||
// 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) {
|
||||
const char* s;
|
||||
bool RegularExpression::find(const char* string)
|
||||
{
|
||||
const char* s;
|
||||
|
||||
this->searchstring = string;
|
||||
this->searchstring = string;
|
||||
|
||||
if (!this->program)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!this->program) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check validity of program.
|
||||
if (UCHARAT(this->program) != MAGIC) {
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::find(): Compiled regular expression corrupted.\n");
|
||||
return 0;
|
||||
}
|
||||
// Check validity of program.
|
||||
if (UCHARAT(this->program) != MAGIC) {
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf(
|
||||
"RegularExpression::find(): Compiled regular expression corrupted.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If there is a "must appear" string, look for it.
|
||||
if (this->regmust != 0) {
|
||||
s = string;
|
||||
while ((s = strchr(s, this->regmust[0])) != 0) {
|
||||
if (strncmp(s, this->regmust, this->regmlen) == 0)
|
||||
break; // Found it.
|
||||
s++;
|
||||
}
|
||||
if (s == 0) // Not present.
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Mark beginning of line for ^ .
|
||||
regbol = string;
|
||||
|
||||
// Simplest case: anchored match need be tried only once.
|
||||
if (this->reganch)
|
||||
return (regtry(string, this->startp, this->endp, this->program) != 0);
|
||||
|
||||
// Messy cases: unanchored match.
|
||||
// If there is a "must appear" string, look for it.
|
||||
if (this->regmust != 0) {
|
||||
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);
|
||||
s++;
|
||||
while ((s = strchr(s, this->regmust[0])) != 0) {
|
||||
if (strncmp(s, this->regmust, this->regmlen) == 0)
|
||||
break; // Found it.
|
||||
s++;
|
||||
}
|
||||
if (s == 0) // Not present.
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
// We don't -- general case.
|
||||
do {
|
||||
if (regtry(s, this->startp, this->endp, this->program))
|
||||
return (1);
|
||||
} while (*s++ != '\0');
|
||||
// Mark beginning of line for ^ .
|
||||
regbol = string;
|
||||
|
||||
// Failure.
|
||||
return (0);
|
||||
// Simplest case: anchored match need be tried only once.
|
||||
if (this->reganch)
|
||||
return (regtry(string, this->startp, this->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);
|
||||
s++;
|
||||
}
|
||||
else
|
||||
// We don't -- general case.
|
||||
do {
|
||||
if (regtry(s, this->startp, this->endp, this->program))
|
||||
return (1);
|
||||
} while (*s++ != '\0');
|
||||
|
||||
// Failure.
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- 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 i;
|
||||
const char* *sp1;
|
||||
const char* *ep;
|
||||
static int regtry(const char* string, const char** start, const char** end,
|
||||
const char* prog)
|
||||
{
|
||||
int i;
|
||||
const char** sp1;
|
||||
const char** ep;
|
||||
|
||||
reginput = string;
|
||||
regstartp = start;
|
||||
regendp = end;
|
||||
reginput = string;
|
||||
regstartp = start;
|
||||
regendp = end;
|
||||
|
||||
sp1 = start;
|
||||
ep = end;
|
||||
for (i = RegularExpression::NSUBEXP; i > 0; i--) {
|
||||
*sp1++ = 0;
|
||||
*ep++ = 0;
|
||||
}
|
||||
if (regmatch(prog + 1)) {
|
||||
start[0] = string;
|
||||
end[0] = reginput;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
sp1 = start;
|
||||
ep = end;
|
||||
for (i = RegularExpression::NSUBEXP; i > 0; i--) {
|
||||
*sp1++ = 0;
|
||||
*ep++ = 0;
|
||||
}
|
||||
if (regmatch(prog + 1)) {
|
||||
start[0] = string;
|
||||
end[0] = reginput;
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regmatch - main matching routine
|
||||
*
|
||||
@@ -984,261 +955,260 @@ static int regtry (const char* string, const char* *start,
|
||||
* by recursion.
|
||||
* 0 failure, 1 success
|
||||
*/
|
||||
static int regmatch (const char* prog) {
|
||||
const char* scan; // Current node.
|
||||
const char* next; // Next node.
|
||||
static int regmatch(const char* prog)
|
||||
{
|
||||
const char* scan; // Current node.
|
||||
const char* next; // Next node.
|
||||
|
||||
scan = prog;
|
||||
scan = prog;
|
||||
|
||||
while (scan != 0) {
|
||||
while (scan != 0) {
|
||||
|
||||
next = regnext(scan);
|
||||
next = regnext(scan);
|
||||
|
||||
switch (OP(scan)) {
|
||||
case BOL:
|
||||
if (reginput != regbol)
|
||||
return (0);
|
||||
break;
|
||||
case EOL:
|
||||
if (*reginput != '\0')
|
||||
return (0);
|
||||
break;
|
||||
case ANY:
|
||||
if (*reginput == '\0')
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case EXACTLY:{
|
||||
size_t len;
|
||||
const char* opnd;
|
||||
switch (OP(scan)) {
|
||||
case BOL:
|
||||
if (reginput != regbol)
|
||||
return (0);
|
||||
break;
|
||||
case EOL:
|
||||
if (*reginput != '\0')
|
||||
return (0);
|
||||
break;
|
||||
case ANY:
|
||||
if (*reginput == '\0')
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case EXACTLY: {
|
||||
size_t len;
|
||||
const char* opnd;
|
||||
|
||||
opnd = OPERAND(scan);
|
||||
// Inline the first character, for speed.
|
||||
if (*opnd != *reginput)
|
||||
return (0);
|
||||
len = strlen(opnd);
|
||||
if (len > 1 && strncmp(opnd, reginput, len) != 0)
|
||||
return (0);
|
||||
reginput += len;
|
||||
}
|
||||
break;
|
||||
case ANYOF:
|
||||
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == 0)
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case ANYBUT:
|
||||
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != 0)
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case NOTHING:
|
||||
break;
|
||||
case BACK:
|
||||
break;
|
||||
case OPEN + 1:
|
||||
case OPEN + 2:
|
||||
case OPEN + 3:
|
||||
case OPEN + 4:
|
||||
case OPEN + 5:
|
||||
case OPEN + 6:
|
||||
case OPEN + 7:
|
||||
case OPEN + 8:
|
||||
case OPEN + 9:{
|
||||
int no;
|
||||
const char* save;
|
||||
opnd = OPERAND(scan);
|
||||
// Inline the first character, for speed.
|
||||
if (*opnd != *reginput)
|
||||
return (0);
|
||||
len = strlen(opnd);
|
||||
if (len > 1 && strncmp(opnd, reginput, len) != 0)
|
||||
return (0);
|
||||
reginput += len;
|
||||
} break;
|
||||
case ANYOF:
|
||||
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == 0)
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case ANYBUT:
|
||||
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != 0)
|
||||
return (0);
|
||||
reginput++;
|
||||
break;
|
||||
case NOTHING:
|
||||
break;
|
||||
case BACK:
|
||||
break;
|
||||
case OPEN + 1:
|
||||
case OPEN + 2:
|
||||
case OPEN + 3:
|
||||
case OPEN + 4:
|
||||
case OPEN + 5:
|
||||
case OPEN + 6:
|
||||
case OPEN + 7:
|
||||
case OPEN + 8:
|
||||
case OPEN + 9: {
|
||||
int no;
|
||||
const char* save;
|
||||
|
||||
no = OP(scan) - OPEN;
|
||||
save = reginput;
|
||||
no = OP(scan) - OPEN;
|
||||
save = reginput;
|
||||
|
||||
if (regmatch(next)) {
|
||||
if (regmatch(next)) {
|
||||
|
||||
//
|
||||
// Don't set startp if some later invocation of the
|
||||
// same parentheses already has.
|
||||
//
|
||||
if (regstartp[no] == 0)
|
||||
regstartp[no] = save;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case CLOSE + 1:
|
||||
case CLOSE + 2:
|
||||
case CLOSE + 3:
|
||||
case CLOSE + 4:
|
||||
case CLOSE + 5:
|
||||
case CLOSE + 6:
|
||||
case CLOSE + 7:
|
||||
case CLOSE + 8:
|
||||
case CLOSE + 9:{
|
||||
int no;
|
||||
const char* save;
|
||||
//
|
||||
// Don't set startp if some later invocation of the
|
||||
// same parentheses already has.
|
||||
//
|
||||
if (regstartp[no] == 0)
|
||||
regstartp[no] = save;
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case CLOSE + 1:
|
||||
case CLOSE + 2:
|
||||
case CLOSE + 3:
|
||||
case CLOSE + 4:
|
||||
case CLOSE + 5:
|
||||
case CLOSE + 6:
|
||||
case CLOSE + 7:
|
||||
case CLOSE + 8:
|
||||
case CLOSE + 9: {
|
||||
int no;
|
||||
const char* save;
|
||||
|
||||
no = OP(scan) - CLOSE;
|
||||
save = reginput;
|
||||
no = OP(scan) - CLOSE;
|
||||
save = reginput;
|
||||
|
||||
if (regmatch(next)) {
|
||||
if (regmatch(next)) {
|
||||
|
||||
//
|
||||
// Don't set endp if some later invocation of the
|
||||
// same parentheses already has.
|
||||
//
|
||||
if (regendp[no] == 0)
|
||||
regendp[no] = save;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case BRANCH:{
|
||||
//
|
||||
// Don't set endp if some later invocation of the
|
||||
// same parentheses already has.
|
||||
//
|
||||
if (regendp[no] == 0)
|
||||
regendp[no] = save;
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case BRANCH: {
|
||||
|
||||
const char* save;
|
||||
const char* save;
|
||||
|
||||
if (OP(next) != BRANCH) // No choice.
|
||||
next = OPERAND(scan); // Avoid recursion.
|
||||
else {
|
||||
do {
|
||||
save = reginput;
|
||||
if (regmatch(OPERAND(scan)))
|
||||
return (1);
|
||||
reginput = save;
|
||||
scan = regnext(scan);
|
||||
} while (scan != 0 && OP(scan) == BRANCH);
|
||||
return (0);
|
||||
// NOTREACHED
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STAR:
|
||||
case PLUS:{
|
||||
char nextch;
|
||||
int no;
|
||||
const char* save;
|
||||
int min_no;
|
||||
|
||||
//
|
||||
// Lookahead to avoid useless match attempts when we know
|
||||
// what character comes next.
|
||||
//
|
||||
nextch = '\0';
|
||||
if (OP(next) == EXACTLY)
|
||||
nextch = *OPERAND(next);
|
||||
min_no = (OP(scan) == STAR) ? 0 : 1;
|
||||
save = reginput;
|
||||
no = regrepeat(OPERAND(scan));
|
||||
while (no >= min_no) {
|
||||
// If it could work, try it.
|
||||
if (nextch == '\0' || *reginput == nextch)
|
||||
if (regmatch(next))
|
||||
return (1);
|
||||
// Couldn't or didn't -- back up.
|
||||
no--;
|
||||
reginput = save + no;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case END:
|
||||
return (1); // Success!
|
||||
|
||||
default:
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::find(): Internal error -- memory corrupted.\n");
|
||||
return 0;
|
||||
if (OP(next) != BRANCH) // No choice.
|
||||
next = OPERAND(scan); // Avoid recursion.
|
||||
else {
|
||||
do {
|
||||
save = reginput;
|
||||
if (regmatch(OPERAND(scan)))
|
||||
return (1);
|
||||
reginput = save;
|
||||
scan = regnext(scan);
|
||||
} while (scan != 0 && OP(scan) == BRANCH);
|
||||
return (0);
|
||||
// NOTREACHED
|
||||
}
|
||||
scan = next;
|
||||
} break;
|
||||
case STAR:
|
||||
case PLUS: {
|
||||
char nextch;
|
||||
int no;
|
||||
const char* save;
|
||||
int min_no;
|
||||
|
||||
//
|
||||
// Lookahead to avoid useless match attempts when we know
|
||||
// what character comes next.
|
||||
//
|
||||
nextch = '\0';
|
||||
if (OP(next) == EXACTLY)
|
||||
nextch = *OPERAND(next);
|
||||
min_no = (OP(scan) == STAR) ? 0 : 1;
|
||||
save = reginput;
|
||||
no = regrepeat(OPERAND(scan));
|
||||
while (no >= min_no) {
|
||||
// If it could work, try it.
|
||||
if (nextch == '\0' || *reginput == nextch)
|
||||
if (regmatch(next))
|
||||
return (1);
|
||||
// Couldn't or didn't -- back up.
|
||||
no--;
|
||||
reginput = save + no;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
// break;
|
||||
case END:
|
||||
return (1); // Success!
|
||||
|
||||
default:
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf(
|
||||
"RegularExpression::find(): Internal error -- memory corrupted.\n");
|
||||
return 0;
|
||||
}
|
||||
scan = next;
|
||||
}
|
||||
|
||||
//
|
||||
// We get here only if there's trouble -- normally "case END" is the
|
||||
// terminating point.
|
||||
//
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("RegularExpression::find(): Internal error -- corrupted pointers.\n");
|
||||
return (0);
|
||||
//
|
||||
// We get here only if there's trouble -- normally "case END" is the
|
||||
// terminating point.
|
||||
//
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf("RegularExpression::find(): Internal error -- corrupted pointers.\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regrepeat - repeatedly match something simple, report how many
|
||||
*/
|
||||
static int regrepeat (const char* p) {
|
||||
int count = 0;
|
||||
const char* scan;
|
||||
const char* opnd;
|
||||
static int regrepeat(const char* p)
|
||||
{
|
||||
int count = 0;
|
||||
const char* scan;
|
||||
const char* opnd;
|
||||
|
||||
scan = reginput;
|
||||
opnd = OPERAND(p);
|
||||
switch (OP(p)) {
|
||||
case ANY:
|
||||
count = int(strlen(scan));
|
||||
scan += count;
|
||||
break;
|
||||
case EXACTLY:
|
||||
while (*opnd == *scan) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
case ANYOF:
|
||||
while (*scan != '\0' && strchr(opnd, *scan) != 0) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
case ANYBUT:
|
||||
while (*scan != '\0' && strchr(opnd, *scan) == 0) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
default: // Oh dear. Called inappropriately.
|
||||
//RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf ("cm RegularExpression::find(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
reginput = scan;
|
||||
return (count);
|
||||
scan = reginput;
|
||||
opnd = OPERAND(p);
|
||||
switch (OP(p)) {
|
||||
case ANY:
|
||||
count = int(strlen(scan));
|
||||
scan += count;
|
||||
break;
|
||||
case EXACTLY:
|
||||
while (*opnd == *scan) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
case ANYOF:
|
||||
while (*scan != '\0' && strchr(opnd, *scan) != 0) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
case ANYBUT:
|
||||
while (*scan != '\0' && strchr(opnd, *scan) == 0) {
|
||||
count++;
|
||||
scan++;
|
||||
}
|
||||
break;
|
||||
default: // Oh dear. Called inappropriately.
|
||||
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
|
||||
printf("cm RegularExpression::find(): Internal error.\n");
|
||||
return 0;
|
||||
}
|
||||
reginput = scan;
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
- regnext - dig the "next" pointer out of a node
|
||||
*/
|
||||
static const char* regnext (const char* p) {
|
||||
int offset;
|
||||
static const char* regnext(const char* p)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (p == ®dummy)
|
||||
return (0);
|
||||
if (p == ®dummy)
|
||||
return (0);
|
||||
|
||||
offset = NEXT(p);
|
||||
if (offset == 0)
|
||||
return (0);
|
||||
offset = NEXT(p);
|
||||
if (offset == 0)
|
||||
return (0);
|
||||
|
||||
if (OP(p) == BACK)
|
||||
return (p - offset);
|
||||
else
|
||||
return (p + offset);
|
||||
if (OP(p) == BACK)
|
||||
return (p - offset);
|
||||
else
|
||||
return (p + offset);
|
||||
}
|
||||
|
||||
static char* regnext (char* p) {
|
||||
int offset;
|
||||
static char* regnext(char* p)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (p == ®dummy)
|
||||
return (0);
|
||||
if (p == ®dummy)
|
||||
return (0);
|
||||
|
||||
offset = NEXT(p);
|
||||
if (offset == 0)
|
||||
return (0);
|
||||
offset = NEXT(p);
|
||||
if (offset == 0)
|
||||
return (0);
|
||||
|
||||
if (OP(p) == BACK)
|
||||
return (p - offset);
|
||||
else
|
||||
return (p + offset);
|
||||
if (OP(p) == BACK)
|
||||
return (p - offset);
|
||||
else
|
||||
return (p + offset);
|
||||
}
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
// Original Copyright notice:
|
||||
// Copyright (C) 1991 Texas Instruments Incorporated.
|
||||
//
|
||||
@@ -38,11 +29,10 @@
|
||||
/* Disable useless Borland warnings. KWSys tries not to force things
|
||||
on its includers, but there is no choice here. */
|
||||
#if defined(__BORLANDC__)
|
||||
# pragma warn -8027 /* function not inlined. */
|
||||
#pragma warn - 8027 /* function not inlined. */
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
/** \class RegularExpression
|
||||
* \brief Implements pattern matching with regular expressions.
|
||||
@@ -68,10 +58,10 @@ namespace @KWSYS_NAMESPACE@
|
||||
* and utilities.
|
||||
*
|
||||
* Example: The perl code
|
||||
*
|
||||
*
|
||||
* $filename =~ m"([a-z]+)\.cc";
|
||||
* print $1;
|
||||
*
|
||||
*
|
||||
* Is written as follows in C++
|
||||
*
|
||||
* RegularExpression re("([a-z]+)\\.cc");
|
||||
@@ -181,28 +171,28 @@ namespace @KWSYS_NAMESPACE@
|
||||
* the line. It would match "drepa qrepb" in "rep drepa qrepb".
|
||||
*
|
||||
*/
|
||||
class @KWSYS_NAMESPACE@_EXPORT RegularExpression
|
||||
class @KWSYS_NAMESPACE@_EXPORT RegularExpression
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Instantiate RegularExpression with program=NULL.
|
||||
*/
|
||||
inline RegularExpression ();
|
||||
inline RegularExpression();
|
||||
|
||||
/**
|
||||
* Instantiate RegularExpression with compiled char*.
|
||||
*/
|
||||
inline RegularExpression (char const*);
|
||||
inline RegularExpression(char const*);
|
||||
|
||||
/**
|
||||
* Instantiate RegularExpression as a copy of another regular expression.
|
||||
*/
|
||||
RegularExpression (RegularExpression const&);
|
||||
RegularExpression(RegularExpression const&);
|
||||
|
||||
/**
|
||||
* Instantiate RegularExpression with compiled string.
|
||||
*/
|
||||
inline RegularExpression (std::string const&);
|
||||
inline RegularExpression(std::string const&);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -213,25 +203,25 @@ public:
|
||||
* Compile a regular expression into internal code
|
||||
* for later pattern matching.
|
||||
*/
|
||||
bool compile (char const*);
|
||||
bool compile(char const*);
|
||||
|
||||
/**
|
||||
* Compile a regular expression into internal code
|
||||
* for later pattern matching.
|
||||
*/
|
||||
inline bool compile (std::string const&);
|
||||
inline bool compile(std::string const&);
|
||||
|
||||
/**
|
||||
* Matches the regular expression to the given string.
|
||||
* Returns true if found, and sets start and end indexes accordingly.
|
||||
*/
|
||||
bool find (char const*);
|
||||
bool find(char const*);
|
||||
|
||||
/**
|
||||
* Matches the regular expression to the given std string.
|
||||
* Returns true if found, and sets start and end indexes accordingly.
|
||||
*/
|
||||
inline bool find (std::string const&);
|
||||
inline bool find(std::string const&);
|
||||
|
||||
/**
|
||||
* Index to start of first find.
|
||||
@@ -246,26 +236,26 @@ public:
|
||||
/**
|
||||
* Copy the given regular expression.
|
||||
*/
|
||||
RegularExpression& operator= (const RegularExpression& rxp);
|
||||
RegularExpression& operator=(const RegularExpression& rxp);
|
||||
|
||||
/**
|
||||
* Returns true if two regular expressions have the same
|
||||
* compiled program for pattern matching.
|
||||
*/
|
||||
bool operator== (RegularExpression const&) const;
|
||||
bool operator==(RegularExpression const&) const;
|
||||
|
||||
/**
|
||||
* Returns true if two regular expressions have different
|
||||
* compiled program for pattern matching.
|
||||
*/
|
||||
inline bool operator!= (RegularExpression const&) const;
|
||||
inline bool operator!=(RegularExpression const&) const;
|
||||
|
||||
/**
|
||||
* Returns true if have the same compiled regular expressions
|
||||
* and the same start and end pointers.
|
||||
*/
|
||||
bool deep_equal (RegularExpression const&) const;
|
||||
|
||||
bool deep_equal(RegularExpression const&) const;
|
||||
|
||||
/**
|
||||
* True if the compiled regexp is valid.
|
||||
*/
|
||||
@@ -274,7 +264,7 @@ public:
|
||||
/**
|
||||
* Marks the regular expression as invalid.
|
||||
*/
|
||||
inline void set_invalid();
|
||||
inline void set_invalid();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -283,25 +273,29 @@ public:
|
||||
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:
|
||||
|
||||
enum
|
||||
{
|
||||
NSUBEXP = 10
|
||||
};
|
||||
|
||||
private:
|
||||
const char* startp[NSUBEXP];
|
||||
const char* endp[NSUBEXP];
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty regular expression.
|
||||
*/
|
||||
inline RegularExpression::RegularExpression ()
|
||||
{
|
||||
inline RegularExpression::RegularExpression()
|
||||
{
|
||||
this->program = 0;
|
||||
}
|
||||
|
||||
@@ -309,20 +303,19 @@ inline RegularExpression::RegularExpression ()
|
||||
* Creates a regular expression from string s, and
|
||||
* compiles s.
|
||||
*/
|
||||
inline RegularExpression::RegularExpression (const char* s)
|
||||
{
|
||||
inline RegularExpression::RegularExpression(const char* s)
|
||||
{
|
||||
this->program = 0;
|
||||
if ( s )
|
||||
{
|
||||
if (s) {
|
||||
this->compile(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a regular expression from string s, and
|
||||
* compiles s.
|
||||
*/
|
||||
inline RegularExpression::RegularExpression (const std::string& s)
|
||||
inline RegularExpression::RegularExpression(const std::string& s)
|
||||
{
|
||||
this->program = 0;
|
||||
this->compile(s);
|
||||
@@ -331,18 +324,18 @@ inline RegularExpression::RegularExpression (const std::string& s)
|
||||
/**
|
||||
* Destroys and frees space allocated for the regular expression.
|
||||
*/
|
||||
inline RegularExpression::~RegularExpression ()
|
||||
inline RegularExpression::~RegularExpression()
|
||||
{
|
||||
//#ifndef _WIN32
|
||||
delete [] this->program;
|
||||
//#endif
|
||||
//#ifndef _WIN32
|
||||
delete[] this->program;
|
||||
//#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a regular expression into internal code
|
||||
* for later pattern matching.
|
||||
*/
|
||||
inline bool RegularExpression::compile (std::string const& s)
|
||||
inline bool RegularExpression::compile(std::string const& s)
|
||||
{
|
||||
return this->compile(s.c_str());
|
||||
}
|
||||
@@ -351,7 +344,7 @@ 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(std::string const& s)
|
||||
{
|
||||
return this->find(s.c_str());
|
||||
}
|
||||
@@ -359,46 +352,42 @@ inline bool RegularExpression::find (std::string const& s)
|
||||
/**
|
||||
* Set the start position for the regular expression.
|
||||
*/
|
||||
inline std::string::size_type RegularExpression::start () const
|
||||
inline std::string::size_type RegularExpression::start() const
|
||||
{
|
||||
return static_cast<std::string::size_type>(
|
||||
this->startp[0] - searchstring);
|
||||
return static_cast<std::string::size_type>(this->startp[0] - searchstring);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the start/end index of the last item found.
|
||||
*/
|
||||
inline std::string::size_type RegularExpression::end () const
|
||||
inline std::string::size_type RegularExpression::end() const
|
||||
{
|
||||
return static_cast<std::string::size_type>(
|
||||
this->endp[0] - searchstring);
|
||||
return static_cast<std::string::size_type>(this->endp[0] - searchstring);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if two regular expressions have different
|
||||
* compiled program for pattern matching.
|
||||
*/
|
||||
inline bool RegularExpression::operator!= (const RegularExpression& r) const
|
||||
inline bool RegularExpression::operator!=(const RegularExpression& r) const
|
||||
{
|
||||
return(!(*this == r));
|
||||
return (!(*this == r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a valid regular expression is compiled
|
||||
* and ready for pattern matching.
|
||||
*/
|
||||
inline bool RegularExpression::is_valid () const
|
||||
inline bool RegularExpression::is_valid() const
|
||||
{
|
||||
return (this->program != 0);
|
||||
}
|
||||
|
||||
|
||||
inline void RegularExpression::set_invalid ()
|
||||
inline void RegularExpression::set_invalid()
|
||||
{
|
||||
//#ifndef _WIN32
|
||||
delete [] this->program;
|
||||
//#endif
|
||||
//#ifndef _WIN32
|
||||
delete[] this->program;
|
||||
//#endif
|
||||
this->program = 0;
|
||||
}
|
||||
|
||||
@@ -407,18 +396,15 @@ 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 static_cast<std::string::size_type>(this->startp[n] - searchstring);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return end index of nth submatch. end(0) is the end of the full match.
|
||||
*/
|
||||
inline std::string::size_type RegularExpression::end(int n) const
|
||||
{
|
||||
return static_cast<std::string::size_type>(
|
||||
this->endp[n] - searchstring);
|
||||
return static_cast<std::string::size_type>(this->endp[n] - searchstring);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,16 +412,12 @@ inline std::string::size_type RegularExpression::end(int n) const
|
||||
*/
|
||||
inline std::string RegularExpression::match(int n) const
|
||||
{
|
||||
if (this->startp[n]==0)
|
||||
{
|
||||
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]));
|
||||
}
|
||||
} else {
|
||||
return std::string(this->startp[n], static_cast<std::string::size_type>(
|
||||
this->endp[n] - this->startp[n]));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
+277
-327
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_SharedForward_h
|
||||
#define @KWSYS_NAMESPACE@_SharedForward_h
|
||||
|
||||
@@ -30,7 +21,8 @@
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL "../lib/foo-1.2"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD CONFIG_DIR_PRE "foo-real"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL "../lib/foo-1.2/foo-real"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL
|
||||
"../lib/foo-1.2/foo-real"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd"
|
||||
@@ -68,16 +60,16 @@
|
||||
/* Disable -Wcast-qual warnings since they are too hard to fix in a
|
||||
cross-platform way. */
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wcast-qual")
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-qual"
|
||||
# endif
|
||||
#if __has_warning("-Wcast-qual")
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(__cplusplus)
|
||||
/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
|
||||
unused parameter using "(param)" syntax (i.e. no cast to void). */
|
||||
# pragma warn -8019
|
||||
/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
|
||||
unused parameter using "(param)" syntax (i.e. no cast to void). */
|
||||
#pragma warn - 8019
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -85,96 +77,107 @@
|
||||
/* Full path to the directory in which this executable is built. Do
|
||||
not include a trailing slash. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD)
|
||||
# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD"
|
||||
#error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD"
|
||||
#endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_DIR_BUILD)
|
||||
# define KWSYS_SHARED_FORWARD_DIR_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD
|
||||
#define KWSYS_SHARED_FORWARD_DIR_BUILD \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD
|
||||
#endif
|
||||
|
||||
/* Library search path for build tree. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD)
|
||||
# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD"
|
||||
#error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD"
|
||||
#endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_PATH_BUILD)
|
||||
# define KWSYS_SHARED_FORWARD_PATH_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD
|
||||
#define KWSYS_SHARED_FORWARD_PATH_BUILD \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD
|
||||
#endif
|
||||
|
||||
/* Library search path for install tree. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL)
|
||||
# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL"
|
||||
#error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL"
|
||||
#endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_PATH_INSTALL)
|
||||
# define KWSYS_SHARED_FORWARD_PATH_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL
|
||||
#define KWSYS_SHARED_FORWARD_PATH_INSTALL \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL
|
||||
#endif
|
||||
|
||||
/* The real executable to which to forward in the build tree. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD)
|
||||
# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD"
|
||||
#error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD"
|
||||
#endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_EXE_BUILD)
|
||||
# define KWSYS_SHARED_FORWARD_EXE_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD
|
||||
#define KWSYS_SHARED_FORWARD_EXE_BUILD \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD
|
||||
#endif
|
||||
|
||||
/* The real executable to which to forward in the install tree. */
|
||||
#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL)
|
||||
# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL"
|
||||
#error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL"
|
||||
#endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_EXE_INSTALL)
|
||||
# define KWSYS_SHARED_FORWARD_EXE_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL
|
||||
#define KWSYS_SHARED_FORWARD_EXE_INSTALL \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL
|
||||
#endif
|
||||
|
||||
/* The configuration name with which this executable was built (Debug/Release). */
|
||||
/* The configuration name with which this executable was built (Debug/Release).
|
||||
*/
|
||||
#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME)
|
||||
# define KWSYS_SHARED_FORWARD_CONFIG_NAME @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME
|
||||
#define KWSYS_SHARED_FORWARD_CONFIG_NAME \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME
|
||||
#else
|
||||
# undef KWSYS_SHARED_FORWARD_CONFIG_NAME
|
||||
#undef KWSYS_SHARED_FORWARD_CONFIG_NAME
|
||||
#endif
|
||||
|
||||
/* Create command line option to replace executable. */
|
||||
#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND)
|
||||
# if !defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
|
||||
# define KWSYS_SHARED_FORWARD_OPTION_COMMAND @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND
|
||||
# endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
|
||||
#define KWSYS_SHARED_FORWARD_OPTION_COMMAND \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND
|
||||
#endif
|
||||
#else
|
||||
# undef KWSYS_SHARED_FORWARD_OPTION_COMMAND
|
||||
#undef KWSYS_SHARED_FORWARD_OPTION_COMMAND
|
||||
#endif
|
||||
|
||||
/* Create command line option to print environment setting and exit. */
|
||||
#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT)
|
||||
# if !defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
|
||||
# define KWSYS_SHARED_FORWARD_OPTION_PRINT @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT
|
||||
# endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
|
||||
#define KWSYS_SHARED_FORWARD_OPTION_PRINT \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT
|
||||
#endif
|
||||
#else
|
||||
# undef KWSYS_SHARED_FORWARD_OPTION_PRINT
|
||||
#undef KWSYS_SHARED_FORWARD_OPTION_PRINT
|
||||
#endif
|
||||
|
||||
/* Create command line option to run ldd or equivalent. */
|
||||
#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD)
|
||||
# if !defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
|
||||
# define KWSYS_SHARED_FORWARD_OPTION_LDD @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD
|
||||
# endif
|
||||
#if !defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
|
||||
#define KWSYS_SHARED_FORWARD_OPTION_LDD \
|
||||
@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD
|
||||
#endif
|
||||
#else
|
||||
# undef KWSYS_SHARED_FORWARD_OPTION_LDD
|
||||
#undef KWSYS_SHARED_FORWARD_OPTION_LDD
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Include needed system headers. */
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
# include <process.h>
|
||||
# define KWSYS_SHARED_FORWARD_ESCAPE_ARGV /* re-escape argv for execvp */
|
||||
#include <windows.h>
|
||||
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#define KWSYS_SHARED_FORWARD_ESCAPE_ARGV /* re-escape argv for execvp */
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <sys/stat.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -182,22 +185,26 @@
|
||||
|
||||
/* The path separator for this platform. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# define KWSYS_SHARED_FORWARD_PATH_SEP ';'
|
||||
# define KWSYS_SHARED_FORWARD_PATH_SLASH '\\'
|
||||
#define KWSYS_SHARED_FORWARD_PATH_SEP ';'
|
||||
#define KWSYS_SHARED_FORWARD_PATH_SLASH '\\'
|
||||
#else
|
||||
# define KWSYS_SHARED_FORWARD_PATH_SEP ':'
|
||||
# define KWSYS_SHARED_FORWARD_PATH_SLASH '/'
|
||||
#define KWSYS_SHARED_FORWARD_PATH_SEP ':'
|
||||
#define KWSYS_SHARED_FORWARD_PATH_SLASH '/'
|
||||
#endif
|
||||
static const char kwsys_shared_forward_path_sep[2] = {KWSYS_SHARED_FORWARD_PATH_SEP, 0};
|
||||
static const char kwsys_shared_forward_path_slash[2] = {KWSYS_SHARED_FORWARD_PATH_SLASH, 0};
|
||||
static const char kwsys_shared_forward_path_sep[2] = {
|
||||
KWSYS_SHARED_FORWARD_PATH_SEP, 0
|
||||
};
|
||||
static const char kwsys_shared_forward_path_slash[2] = {
|
||||
KWSYS_SHARED_FORWARD_PATH_SLASH, 0
|
||||
};
|
||||
|
||||
/* The maximum length of a file name. */
|
||||
#if defined(PATH_MAX)
|
||||
# define KWSYS_SHARED_FORWARD_MAXPATH PATH_MAX
|
||||
#define KWSYS_SHARED_FORWARD_MAXPATH PATH_MAX
|
||||
#elif defined(MAXPATHLEN)
|
||||
# define KWSYS_SHARED_FORWARD_MAXPATH MAXPATHLEN
|
||||
#define KWSYS_SHARED_FORWARD_MAXPATH MAXPATHLEN
|
||||
#else
|
||||
# define KWSYS_SHARED_FORWARD_MAXPATH 16384
|
||||
#define KWSYS_SHARED_FORWARD_MAXPATH 16384
|
||||
#endif
|
||||
|
||||
/* Select the environment variable holding the shared library runtime
|
||||
@@ -206,82 +213,82 @@ static const char kwsys_shared_forward_path_slash[2] = {KWSYS_SHARED_FORWARD_PAT
|
||||
|
||||
/* Linux */
|
||||
#if defined(__linux)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
|
||||
/* FreeBSD */
|
||||
#elif defined(__FreeBSD__)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
|
||||
/* OpenBSD */
|
||||
#elif defined(__OpenBSD__)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
|
||||
/* OSX */
|
||||
#elif defined(__APPLE__)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "otool", "-L"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 2
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "DYLD_LIBRARY_PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "otool", "-L"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 2
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "DYLD_LIBRARY_PATH"
|
||||
|
||||
/* AIX */
|
||||
#elif defined(_AIX)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "dump", "-H"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 2
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LIBPATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "dump", "-H"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 2
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LIBPATH"
|
||||
|
||||
/* SUN */
|
||||
#elif defined(__sun)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# include <sys/isa_defs.h>
|
||||
# if defined(_ILP32)
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
# elif defined(_LP64)
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH_64"
|
||||
# endif
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#include <sys/isa_defs.h>
|
||||
#if defined(_ILP32)
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#elif defined(_LP64)
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH_64"
|
||||
#endif
|
||||
|
||||
/* HP-UX */
|
||||
#elif defined(__hpux)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "chatr"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# if defined(__LP64__)
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
# else
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "SHLIB_PATH"
|
||||
# endif
|
||||
#define KWSYS_SHARED_FORWARD_LDD "chatr"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#if defined(__LP64__)
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#else
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "SHLIB_PATH"
|
||||
#endif
|
||||
|
||||
/* SGI MIPS */
|
||||
#elif defined(__sgi) && defined(_MIPS_SIM)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# if _MIPS_SIM == _ABIO32
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
# elif _MIPS_SIM == _ABIN32
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARYN32_PATH"
|
||||
# elif _MIPS_SIM == _ABI64
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY64_PATH"
|
||||
# endif
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#elif _MIPS_SIM == _ABIN32
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARYN32_PATH"
|
||||
#elif _MIPS_SIM == _ABI64
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY64_PATH"
|
||||
#endif
|
||||
|
||||
/* Cygwin */
|
||||
#elif defined(__CYGWIN__)
|
||||
# define KWSYS_SHARED_FORWARD_LDD "cygcheck" /* TODO: cygwin 1.7 has ldd */
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "cygcheck" /* TODO: cygwin 1.7 has ldd */
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "PATH"
|
||||
|
||||
/* Windows */
|
||||
#elif defined(_WIN32)
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "PATH"
|
||||
|
||||
/* Guess on this unknown system. */
|
||||
#else
|
||||
# define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
# define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#define KWSYS_SHARED_FORWARD_LDD "ldd"
|
||||
#define KWSYS_SHARED_FORWARD_LDD_N 1
|
||||
#define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
|
||||
#endif
|
||||
|
||||
#ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV
|
||||
@@ -312,45 +319,37 @@ static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in)
|
||||
info.quote = 0;
|
||||
|
||||
/* Scan the string for characters that require escaping or quoting. */
|
||||
for(c=in; *c; ++c)
|
||||
{
|
||||
for (c = in; *c; ++c) {
|
||||
/* Check whether this character needs quotes. */
|
||||
if(strchr(" \t?'#&<>|^", *c))
|
||||
{
|
||||
if (strchr(" \t?'#&<>|^", *c)) {
|
||||
info.quote = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* On Windows only backslashes and double-quotes need escaping. */
|
||||
if(*c == '\\')
|
||||
{
|
||||
if (*c == '\\') {
|
||||
/* Found a backslash. It may need to be escaped later. */
|
||||
++windows_backslashes;
|
||||
}
|
||||
else if(*c == '"')
|
||||
{
|
||||
} else if (*c == '"') {
|
||||
/* Found a double-quote. We need to escape it and all
|
||||
immediately preceding backslashes. */
|
||||
info.size += windows_backslashes + 1;
|
||||
windows_backslashes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Found another character. This eliminates the possibility
|
||||
that any immediately preceding backslashes will be
|
||||
escaped. */
|
||||
windows_backslashes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the argument needs surrounding quotes. */
|
||||
if(info.quote)
|
||||
{
|
||||
if (info.quote) {
|
||||
/* Surrounding quotes are needed. Allocate space for them. */
|
||||
info.size += 2;
|
||||
|
||||
/* We must escape all ending backslashes when quoting on windows. */
|
||||
info.size += windows_backslashes;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -365,57 +364,47 @@ static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out)
|
||||
int windows_backslashes = 0;
|
||||
|
||||
/* Whether the argument must be quoted. */
|
||||
if(info.quote)
|
||||
{
|
||||
if (info.quote) {
|
||||
/* Add the opening quote for this argument. */
|
||||
*out++ = '"';
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan the string for characters that require escaping or quoting. */
|
||||
for(c=info.arg; *c; ++c)
|
||||
{
|
||||
for (c = info.arg; *c; ++c) {
|
||||
/* On Windows only backslashes and double-quotes need escaping. */
|
||||
if(*c == '\\')
|
||||
{
|
||||
if (*c == '\\') {
|
||||
/* Found a backslash. It may need to be escaped later. */
|
||||
++windows_backslashes;
|
||||
}
|
||||
else if(*c == '"')
|
||||
{
|
||||
} else if (*c == '"') {
|
||||
/* Found a double-quote. Escape all immediately preceding
|
||||
backslashes. */
|
||||
while(windows_backslashes > 0)
|
||||
{
|
||||
while (windows_backslashes > 0) {
|
||||
--windows_backslashes;
|
||||
*out++ = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the backslash to escape the double-quote. */
|
||||
*out++ = '\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* We encountered a normal character. This eliminates any
|
||||
escaping needed for preceding backslashes. */
|
||||
windows_backslashes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store this character. */
|
||||
*out++ = *c;
|
||||
}
|
||||
}
|
||||
|
||||
if(info.quote)
|
||||
{
|
||||
if (info.quote) {
|
||||
/* Add enough backslashes to escape any trailing ones. */
|
||||
while(windows_backslashes > 0)
|
||||
{
|
||||
while (windows_backslashes > 0) {
|
||||
--windows_backslashes;
|
||||
*out++ = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the closing quote for this argument. */
|
||||
*out++ = '"';
|
||||
}
|
||||
}
|
||||
|
||||
/* Store a terminating null without incrementing. */
|
||||
*out = 0;
|
||||
@@ -430,8 +419,8 @@ static int kwsys_shared_forward_realpath(const char* in_path, char* out_path)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Implementation for Windows. */
|
||||
DWORD n = GetFullPathNameA(in_path, KWSYS_SHARED_FORWARD_MAXPATH,
|
||||
out_path, 0);
|
||||
DWORD n =
|
||||
GetFullPathNameA(in_path, KWSYS_SHARED_FORWARD_MAXPATH, out_path, 0);
|
||||
return n > 0 && n <= KWSYS_SHARED_FORWARD_MAXPATH;
|
||||
#else
|
||||
/* Implementation for UNIX. */
|
||||
@@ -445,11 +434,10 @@ static int kwsys_shared_forward_samepath(const char* file1, const char* file2)
|
||||
#if defined(_WIN32)
|
||||
int result = 0;
|
||||
HANDLE h1 = CreateFileA(file1, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
HANDLE h2 = CreateFileA(file2, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if(h1 != INVALID_HANDLE_VALUE && h2 != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (h1 != INVALID_HANDLE_VALUE && h2 != INVALID_HANDLE_VALUE) {
|
||||
BY_HANDLE_FILE_INFORMATION fi1;
|
||||
BY_HANDLE_FILE_INFORMATION fi2;
|
||||
GetFileInformationByHandle(h1, &fi1);
|
||||
@@ -457,10 +445,10 @@ static int kwsys_shared_forward_samepath(const char* file1, const char* file2)
|
||||
result = (fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber &&
|
||||
fi1.nFileIndexHigh == fi2.nFileIndexHigh &&
|
||||
fi1.nFileIndexLow == fi2.nFileIndexLow);
|
||||
}
|
||||
CloseHandle(h1);
|
||||
CloseHandle(h2);
|
||||
return result;
|
||||
}
|
||||
CloseHandle(h1);
|
||||
CloseHandle(h2);
|
||||
return result;
|
||||
#else
|
||||
struct stat fs1, fs2;
|
||||
return (stat(file1, &fs1) == 0 && stat(file2, &fs2) == 0 &&
|
||||
@@ -477,17 +465,16 @@ static void kwsys_shared_forward_strerror(char* message)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Implementation for Windows. */
|
||||
DWORD original = GetLastError();
|
||||
DWORD length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
message, KWSYS_SHARED_FORWARD_MAXPATH, 0);
|
||||
if(length < 1 || length > KWSYS_SHARED_FORWARD_MAXPATH)
|
||||
{
|
||||
DWORD length =
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, original, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
message, KWSYS_SHARED_FORWARD_MAXPATH, 0);
|
||||
if (length < 1 || length > KWSYS_SHARED_FORWARD_MAXPATH) {
|
||||
/* FormatMessage failed. Use a default message. */
|
||||
_snprintf(message, KWSYS_SHARED_FORWARD_MAXPATH,
|
||||
"Error 0x%X (FormatMessage failed with error 0x%X)",
|
||||
original, GetLastError());
|
||||
}
|
||||
"Error 0x%X (FormatMessage failed with error 0x%X)", original,
|
||||
GetLastError());
|
||||
}
|
||||
#else
|
||||
/* Implementation for UNIX. */
|
||||
strcpy(message, strerror(errno));
|
||||
@@ -503,28 +490,28 @@ static void kwsys_shared_forward_execvp(const char* cmd,
|
||||
/* Count the number of arguments. */
|
||||
int argc = 0;
|
||||
{
|
||||
char const* const* argvc;
|
||||
for(argvc = argv; *argvc; ++argvc,++argc) {}
|
||||
char const* const* argvc;
|
||||
for (argvc = argv; *argvc; ++argvc, ++argc) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the escaped arguments. */
|
||||
{
|
||||
char** nargv = (char**)malloc((argc+1) * sizeof(char*));
|
||||
int i;
|
||||
for(i=0; i < argc; ++i)
|
||||
{
|
||||
kwsys_sf_arg_info info = kwsys_sf_get_arg_info(argv[i]);
|
||||
nargv[i] = (char*)malloc(info.size);
|
||||
kwsys_sf_get_arg(info, nargv[i]);
|
||||
char** nargv = (char**)malloc((argc + 1) * sizeof(char*));
|
||||
int i;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
kwsys_sf_arg_info info = kwsys_sf_get_arg_info(argv[i]);
|
||||
nargv[i] = (char*)malloc(info.size);
|
||||
kwsys_sf_get_arg(info, nargv[i]);
|
||||
}
|
||||
nargv[argc] = 0;
|
||||
nargv[argc] = 0;
|
||||
|
||||
/* Replace the command line to be used. */
|
||||
argv = (char const* const*)nargv;
|
||||
/* Replace the command line to be used. */
|
||||
argv = (char const* const*)nargv;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Invoke the child process. */
|
||||
/* Invoke the child process. */
|
||||
#if defined(_MSC_VER)
|
||||
_execvp(cmd, argv);
|
||||
#elif defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
@@ -541,40 +528,33 @@ static void kwsys_shared_forward_dirname(const char* begin, char* result)
|
||||
/* Find the location of the last slash. */
|
||||
int last_slash_index = -1;
|
||||
const char* end = begin + strlen(begin);
|
||||
for(;begin <= end && last_slash_index < 0; --end)
|
||||
{
|
||||
if(*end == '/' || *end == '\\')
|
||||
{
|
||||
last_slash_index = (int)(end-begin);
|
||||
}
|
||||
for (; begin <= end && last_slash_index < 0; --end) {
|
||||
if (*end == '/' || *end == '\\') {
|
||||
last_slash_index = (int)(end - begin);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle each case of the index of the last slash. */
|
||||
if(last_slash_index < 0)
|
||||
{
|
||||
if (last_slash_index < 0) {
|
||||
/* No slashes. */
|
||||
strcpy(result, ".");
|
||||
}
|
||||
else if(last_slash_index == 0)
|
||||
{
|
||||
} else if (last_slash_index == 0) {
|
||||
/* Only one leading slash. */
|
||||
strcpy(result, kwsys_shared_forward_path_slash);
|
||||
}
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
else if(last_slash_index == 2 && begin[1] == ':')
|
||||
{
|
||||
else if (last_slash_index == 2 && begin[1] == ':') {
|
||||
/* Only one leading drive letter and slash. */
|
||||
strncpy(result, begin, (size_t)last_slash_index);
|
||||
result[last_slash_index] = KWSYS_SHARED_FORWARD_PATH_SLASH;
|
||||
result[last_slash_index+1] = 0;
|
||||
}
|
||||
result[last_slash_index + 1] = 0;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
else {
|
||||
/* A non-leading slash. */
|
||||
strncpy(result, begin, (size_t)last_slash_index);
|
||||
result[last_slash_index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -582,23 +562,20 @@ static void kwsys_shared_forward_dirname(const char* begin, char* result)
|
||||
static int kwsys_shared_forward_is_executable(const char* f)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
# define KWSYS_SHARED_FORWARD_ACCESS _access
|
||||
#define KWSYS_SHARED_FORWARD_ACCESS _access
|
||||
#else
|
||||
# define KWSYS_SHARED_FORWARD_ACCESS access
|
||||
#define KWSYS_SHARED_FORWARD_ACCESS access
|
||||
#endif
|
||||
#if defined(X_OK)
|
||||
# define KWSYS_SHARED_FORWARD_ACCESS_OK X_OK
|
||||
#define KWSYS_SHARED_FORWARD_ACCESS_OK X_OK
|
||||
#else
|
||||
# define KWSYS_SHARED_FORWARD_ACCESS_OK 04
|
||||
#define KWSYS_SHARED_FORWARD_ACCESS_OK 04
|
||||
#endif
|
||||
if(KWSYS_SHARED_FORWARD_ACCESS(f, KWSYS_SHARED_FORWARD_ACCESS_OK) == 0)
|
||||
{
|
||||
if (KWSYS_SHARED_FORWARD_ACCESS(f, KWSYS_SHARED_FORWARD_ACCESS_OK) == 0) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -608,66 +585,60 @@ static int kwsys_shared_forward_self_path(const char* argv0, char* result)
|
||||
/* Check whether argv0 has a slash. */
|
||||
int has_slash = 0;
|
||||
const char* p = argv0;
|
||||
for(;*p && !has_slash; ++p)
|
||||
{
|
||||
if(*p == '/' || *p == '\\')
|
||||
{
|
||||
for (; *p && !has_slash; ++p) {
|
||||
if (*p == '/' || *p == '\\') {
|
||||
has_slash = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(has_slash)
|
||||
{
|
||||
if (has_slash) {
|
||||
/* There is a slash. Use the dirname of the given location. */
|
||||
kwsys_shared_forward_dirname(argv0, result);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* There is no slash. Search the PATH for the executable. */
|
||||
const char* path = getenv("PATH");
|
||||
const char* begin = path;
|
||||
const char* end = begin + (begin?strlen(begin):0);
|
||||
const char* end = begin + (begin ? strlen(begin) : 0);
|
||||
const char* first = begin;
|
||||
while(first != end)
|
||||
{
|
||||
while (first != end) {
|
||||
/* Store the end of this path entry. */
|
||||
const char* last;
|
||||
|
||||
/* Skip all path separators. */
|
||||
for(;*first && *first == KWSYS_SHARED_FORWARD_PATH_SEP; ++first);
|
||||
for (; *first && *first == KWSYS_SHARED_FORWARD_PATH_SEP; ++first)
|
||||
;
|
||||
|
||||
/* Find the next separator. */
|
||||
for(last = first;*last && *last != KWSYS_SHARED_FORWARD_PATH_SEP; ++last);
|
||||
for (last = first; *last && *last != KWSYS_SHARED_FORWARD_PATH_SEP;
|
||||
++last)
|
||||
;
|
||||
|
||||
/* If we got a non-empty directory, look for the executable there. */
|
||||
if(first < last)
|
||||
{
|
||||
if (first < last) {
|
||||
/* Determine the length without trailing slash. */
|
||||
size_t length = (size_t)(last-first);
|
||||
if(*(last-1) == '/' || *(last-1) == '\\')
|
||||
{
|
||||
size_t length = (size_t)(last - first);
|
||||
if (*(last - 1) == '/' || *(last - 1) == '\\') {
|
||||
--length;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct the name of the executable in this location. */
|
||||
strncpy(result, first, length);
|
||||
result[length] = KWSYS_SHARED_FORWARD_PATH_SLASH;
|
||||
strcpy(result+(length)+1, argv0);
|
||||
strcpy(result + (length) + 1, argv0);
|
||||
|
||||
/* Check if it exists and is executable. */
|
||||
if(kwsys_shared_forward_is_executable(result))
|
||||
{
|
||||
if (kwsys_shared_forward_is_executable(result)) {
|
||||
/* Found it. */
|
||||
result[length] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the next directory in the path. */
|
||||
first = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We could not find the executable. */
|
||||
return 0;
|
||||
@@ -677,42 +648,36 @@ static int kwsys_shared_forward_self_path(const char* argv0, char* result)
|
||||
/* Function to convert a specified path to a full path. If it is not
|
||||
already full, it is taken relative to the self path. */
|
||||
static int kwsys_shared_forward_fullpath(const char* self_path,
|
||||
const char* in_path,
|
||||
char* result,
|
||||
const char* in_path, char* result,
|
||||
const char* desc)
|
||||
{
|
||||
/* Check the specified path type. */
|
||||
if(in_path[0] == '/')
|
||||
{
|
||||
if (in_path[0] == '/') {
|
||||
/* Already a full path. */
|
||||
strcpy(result, in_path);
|
||||
}
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
else if(in_path[0] && in_path[1] == ':')
|
||||
{
|
||||
else if (in_path[0] && in_path[1] == ':') {
|
||||
/* Already a full path. */
|
||||
strcpy(result, in_path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
else {
|
||||
/* Relative to self path. */
|
||||
char temp_path[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
strcpy(temp_path, self_path);
|
||||
strcat(temp_path, kwsys_shared_forward_path_slash);
|
||||
strcat(temp_path, in_path);
|
||||
if(!kwsys_shared_forward_realpath(temp_path, result))
|
||||
{
|
||||
if(desc)
|
||||
{
|
||||
if (!kwsys_shared_forward_realpath(temp_path, result)) {
|
||||
if (desc) {
|
||||
char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
kwsys_shared_forward_strerror(msgbuf);
|
||||
fprintf(stderr, "Error converting %s \"%s\" to real path: %s\n",
|
||||
desc, temp_path, msgbuf);
|
||||
}
|
||||
return 0;
|
||||
fprintf(stderr, "Error converting %s \"%s\" to real path: %s\n", desc,
|
||||
temp_path, msgbuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -723,16 +688,20 @@ static int kwsys_shared_forward_get_settings(const char* self_path,
|
||||
char* ldpath, char* exe)
|
||||
{
|
||||
/* Possible search paths. */
|
||||
static const char* search_path_build[] = {KWSYS_SHARED_FORWARD_PATH_BUILD, 0};
|
||||
static const char* search_path_install[] = {KWSYS_SHARED_FORWARD_PATH_INSTALL, 0};
|
||||
static const char* search_path_build[] = { KWSYS_SHARED_FORWARD_PATH_BUILD,
|
||||
0 };
|
||||
static const char* search_path_install[] = {
|
||||
KWSYS_SHARED_FORWARD_PATH_INSTALL, 0
|
||||
};
|
||||
|
||||
/* Chosen paths. */
|
||||
const char** search_path;
|
||||
const char* exe_path;
|
||||
|
||||
/* Get the real name of the build and self paths. */
|
||||
/* Get the real name of the build and self paths. */
|
||||
#if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
|
||||
char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD "/" KWSYS_SHARED_FORWARD_CONFIG_NAME;
|
||||
char build_path[] =
|
||||
KWSYS_SHARED_FORWARD_DIR_BUILD "/" KWSYS_SHARED_FORWARD_CONFIG_NAME;
|
||||
char self_path_logical[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
#else
|
||||
char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD;
|
||||
@@ -740,19 +709,17 @@ static int kwsys_shared_forward_get_settings(const char* self_path,
|
||||
#endif
|
||||
char build_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
char self_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
if(!kwsys_shared_forward_realpath(self_path, self_path_real))
|
||||
{
|
||||
if (!kwsys_shared_forward_realpath(self_path, self_path_real)) {
|
||||
char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
kwsys_shared_forward_strerror(msgbuf);
|
||||
fprintf(stderr, "Error converting self path \"%s\" to real path: %s\n",
|
||||
self_path, msgbuf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether we are running in the build tree or an install tree. */
|
||||
if(kwsys_shared_forward_realpath(build_path, build_path_real) &&
|
||||
kwsys_shared_forward_samepath(self_path_real, build_path_real))
|
||||
{
|
||||
if (kwsys_shared_forward_realpath(build_path, build_path_real) &&
|
||||
kwsys_shared_forward_samepath(self_path_real, build_path_real)) {
|
||||
/* Running in build tree. Use the build path and exe. */
|
||||
search_path = search_path_build;
|
||||
#if defined(_WIN32)
|
||||
@@ -765,9 +732,7 @@ static int kwsys_shared_forward_get_settings(const char* self_path,
|
||||
/* Remove the configuration directory from self_path. */
|
||||
kwsys_shared_forward_dirname(self_path, self_path_logical);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Running in install tree. Use the install path and exe. */
|
||||
search_path = search_path_install;
|
||||
#if defined(_WIN32)
|
||||
@@ -780,35 +745,31 @@ static int kwsys_shared_forward_get_settings(const char* self_path,
|
||||
/* Use the original self path directory. */
|
||||
strcpy(self_path_logical, self_path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct the runtime search path. */
|
||||
{
|
||||
const char** dir;
|
||||
for(dir = search_path; *dir; ++dir)
|
||||
{
|
||||
/* Add separator between path components. */
|
||||
if(dir != search_path)
|
||||
{
|
||||
strcat(ldpath, kwsys_shared_forward_path_sep);
|
||||
const char** dir;
|
||||
for (dir = search_path; *dir; ++dir) {
|
||||
/* Add separator between path components. */
|
||||
if (dir != search_path) {
|
||||
strcat(ldpath, kwsys_shared_forward_path_sep);
|
||||
}
|
||||
|
||||
/* Add this path component. */
|
||||
if(!kwsys_shared_forward_fullpath(self_path_logical, *dir,
|
||||
ldpath+strlen(ldpath),
|
||||
"runtime path entry"))
|
||||
{
|
||||
return 0;
|
||||
/* Add this path component. */
|
||||
if (!kwsys_shared_forward_fullpath(self_path_logical, *dir,
|
||||
ldpath + strlen(ldpath),
|
||||
"runtime path entry")) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct the executable location. */
|
||||
if(!kwsys_shared_forward_fullpath(self_path_logical, exe_path, exe,
|
||||
"executable file"))
|
||||
{
|
||||
if (!kwsys_shared_forward_fullpath(self_path_logical, exe_path, exe,
|
||||
"executable file")) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -820,15 +781,15 @@ static void kwsys_shared_forward_print_failure(char const* const* argv)
|
||||
char const* const* arg = argv;
|
||||
kwsys_shared_forward_strerror(msg);
|
||||
fprintf(stderr, "Error running");
|
||||
for(; *arg; ++arg)
|
||||
{
|
||||
for (; *arg; ++arg) {
|
||||
fprintf(stderr, " \"%s\"", *arg);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ": %s\n", msg);
|
||||
}
|
||||
|
||||
/* Static storage space to store the updated environment variable. */
|
||||
static char kwsys_shared_forward_ldpath[65535] = KWSYS_SHARED_FORWARD_LDPATH "=";
|
||||
static char kwsys_shared_forward_ldpath[65535] =
|
||||
KWSYS_SHARED_FORWARD_LDPATH "=";
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Main driver function to be called from main. */
|
||||
@@ -837,74 +798,67 @@ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in)
|
||||
char const** argv = (char const**)argv_in;
|
||||
/* Get the directory containing this executable. */
|
||||
char self_path[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
if(kwsys_shared_forward_self_path(argv[0], self_path))
|
||||
{
|
||||
if (kwsys_shared_forward_self_path(argv[0], self_path)) {
|
||||
/* Found this executable. Use it to get the library directory. */
|
||||
char exe[KWSYS_SHARED_FORWARD_MAXPATH];
|
||||
if(kwsys_shared_forward_get_settings(self_path,
|
||||
kwsys_shared_forward_ldpath, exe))
|
||||
{
|
||||
if (kwsys_shared_forward_get_settings(self_path,
|
||||
kwsys_shared_forward_ldpath, exe)) {
|
||||
/* Append the old runtime search path. */
|
||||
const char* old_ldpath = getenv(KWSYS_SHARED_FORWARD_LDPATH);
|
||||
if(old_ldpath)
|
||||
{
|
||||
if (old_ldpath) {
|
||||
strcat(kwsys_shared_forward_ldpath, kwsys_shared_forward_path_sep);
|
||||
strcat(kwsys_shared_forward_ldpath, old_ldpath);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the environment variable. */
|
||||
putenv(kwsys_shared_forward_ldpath);
|
||||
|
||||
#if defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
|
||||
/* Look for the command line replacement option. */
|
||||
if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_COMMAND) == 0)
|
||||
{
|
||||
if(argc > 2)
|
||||
{
|
||||
if (argc > 1 &&
|
||||
strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_COMMAND) == 0) {
|
||||
if (argc > 2) {
|
||||
/* Use the command line given. */
|
||||
strcpy(exe, argv[2]);
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* The option was not given an executable. */
|
||||
fprintf(stderr, "Option " KWSYS_SHARED_FORWARD_OPTION_COMMAND
|
||||
" must be followed by a command line.\n");
|
||||
" must be followed by a command line.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
|
||||
/* Look for the print command line option. */
|
||||
if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_PRINT) == 0)
|
||||
{
|
||||
if (argc > 1 &&
|
||||
strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_PRINT) == 0) {
|
||||
fprintf(stdout, "%s\n", kwsys_shared_forward_ldpath);
|
||||
fprintf(stdout, "%s\n", exe);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
|
||||
/* Look for the ldd command line option. */
|
||||
if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_LDD) == 0)
|
||||
{
|
||||
# if defined(KWSYS_SHARED_FORWARD_LDD)
|
||||
if (argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_LDD) == 0) {
|
||||
#if defined(KWSYS_SHARED_FORWARD_LDD)
|
||||
/* Use the named ldd-like executable and arguments. */
|
||||
char const* ldd_argv[] = {KWSYS_SHARED_FORWARD_LDD, 0, 0};
|
||||
char const* ldd_argv[] = { KWSYS_SHARED_FORWARD_LDD, 0, 0 };
|
||||
ldd_argv[KWSYS_SHARED_FORWARD_LDD_N] = exe;
|
||||
kwsys_shared_forward_execvp(ldd_argv[0], ldd_argv);
|
||||
|
||||
/* Report why execution failed. */
|
||||
kwsys_shared_forward_print_failure(ldd_argv);
|
||||
return 1;
|
||||
# else
|
||||
#else
|
||||
/* We have no ldd-like executable available on this platform. */
|
||||
fprintf(stderr, "No ldd-like tool is known to this executable.\n");
|
||||
return 1;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Replace this process with the real executable. */
|
||||
@@ -913,17 +867,13 @@ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in)
|
||||
|
||||
/* Report why execution failed. */
|
||||
kwsys_shared_forward_print_failure(argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Could not convert self path to the library directory. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Could not find this executable. */
|
||||
fprintf(stderr, "Error locating executable \"%s\".\n", argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Avoid unused argument warning. */
|
||||
(void)argc;
|
||||
@@ -934,11 +884,11 @@ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in)
|
||||
|
||||
/* Restore warning stack. */
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wcast-qual")
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
#if __has_warning("-Wcast-qual")
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
# error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once."
|
||||
#error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once."
|
||||
#endif
|
||||
+41
-56
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifdef KWSYS_STRING_C
|
||||
/*
|
||||
All code in this source file is conditionally compiled to work-around
|
||||
@@ -23,53 +14,49 @@ condition blocks the compiler from seeing the symbols defined here.
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "String.h.in"
|
||||
#include "String.h.in"
|
||||
#endif
|
||||
|
||||
/* Select an implementation for strcasecmp. */
|
||||
#if defined(_MSC_VER)
|
||||
# define KWSYS_STRING_USE_STRICMP
|
||||
# include <string.h>
|
||||
#define KWSYS_STRING_USE_STRICMP
|
||||
#include <string.h>
|
||||
#elif defined(__GNUC__)
|
||||
# define KWSYS_STRING_USE_STRCASECMP
|
||||
# include <strings.h>
|
||||
#define KWSYS_STRING_USE_STRCASECMP
|
||||
#include <strings.h>
|
||||
#else
|
||||
/* Table to convert upper case letters to lower case and leave all
|
||||
other characters alone. */
|
||||
static char kwsysString_strcasecmp_tolower[] =
|
||||
{
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
|
||||
static char kwsysString_strcasecmp_tolower[] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010',
|
||||
'\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021',
|
||||
'\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032',
|
||||
'\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043',
|
||||
'\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054',
|
||||
'\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065',
|
||||
'\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076',
|
||||
'\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160',
|
||||
'\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171',
|
||||
'\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142',
|
||||
'\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153',
|
||||
'\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164',
|
||||
'\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175',
|
||||
'\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206',
|
||||
'\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230',
|
||||
'\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241',
|
||||
'\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252',
|
||||
'\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263',
|
||||
'\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274',
|
||||
'\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305',
|
||||
'\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316',
|
||||
'\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340',
|
||||
'\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351',
|
||||
'\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362',
|
||||
'\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373',
|
||||
'\374', '\375', '\376', '\377'
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -85,9 +72,8 @@ int kwsysString_strcasecmp(const char* lhs, const char* rhs)
|
||||
unsigned char const* us1 = (unsigned char const*)lhs;
|
||||
unsigned char const* us2 = (unsigned char const*)rhs;
|
||||
int result;
|
||||
while((result = lower[*us1] - lower[*us2++], result == 0) && *us1++)
|
||||
{
|
||||
}
|
||||
while ((result = lower[*us1] - lower[*us2++], result == 0) && *us1++) {
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
@@ -104,10 +90,9 @@ int kwsysString_strncasecmp(const char* lhs, const char* rhs, size_t n)
|
||||
unsigned char const* us1 = (unsigned char const*)lhs;
|
||||
unsigned char const* us2 = (unsigned char const*)rhs;
|
||||
int result = 0;
|
||||
while(n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++)
|
||||
{
|
||||
while (n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++) {
|
||||
--n;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
+13
-23
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_String_h
|
||||
#define @KWSYS_NAMESPACE@_String_h
|
||||
|
||||
@@ -21,17 +12,16 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysString_strcasecmp kwsys_ns(String_strcasecmp)
|
||||
# define kwsysString_strncasecmp kwsys_ns(String_strncasecmp)
|
||||
#define kwsysString_strcasecmp kwsys_ns(String_strcasecmp)
|
||||
#define kwsysString_strncasecmp kwsys_ns(String_strncasecmp)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -56,12 +46,12 @@ kwsysEXPORT int kwsysString_strncasecmp(const char* lhs, const char* rhs,
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysString_strcasecmp
|
||||
# undef kwsysString_strncasecmp
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysString_strcasecmp
|
||||
#undef kwsysString_strncasecmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+31
-31
@@ -1,21 +1,11 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_String_hxx
|
||||
#define @KWSYS_NAMESPACE@_String_hxx
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
/** \class String
|
||||
* \brief Short-name version of the STL basic_string class template.
|
||||
@@ -25,39 +15,49 @@ namespace @KWSYS_NAMESPACE@
|
||||
* simply a subclass of this type with the same interface so that the
|
||||
* name is shorter in debugging symbols and error messages.
|
||||
*/
|
||||
class String: public std::string
|
||||
class String : public std::string
|
||||
{
|
||||
/** The original string type. */
|
||||
typedef std::string stl_string;
|
||||
|
||||
public:
|
||||
|
||||
/** String member types. */
|
||||
typedef stl_string::value_type value_type;
|
||||
typedef stl_string::pointer pointer;
|
||||
typedef stl_string::reference reference;
|
||||
typedef stl_string::const_reference const_reference;
|
||||
typedef stl_string::size_type size_type;
|
||||
typedef stl_string::difference_type difference_type;
|
||||
typedef stl_string::iterator iterator;
|
||||
typedef stl_string::const_iterator const_iterator;
|
||||
typedef stl_string::reverse_iterator reverse_iterator;
|
||||
typedef stl_string::value_type value_type;
|
||||
typedef stl_string::pointer pointer;
|
||||
typedef stl_string::reference reference;
|
||||
typedef stl_string::const_reference const_reference;
|
||||
typedef stl_string::size_type size_type;
|
||||
typedef stl_string::difference_type difference_type;
|
||||
typedef stl_string::iterator iterator;
|
||||
typedef stl_string::const_iterator const_iterator;
|
||||
typedef stl_string::reverse_iterator reverse_iterator;
|
||||
typedef stl_string::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
/** String constructors. */
|
||||
String(): stl_string() {}
|
||||
String(const value_type* s): stl_string(s) {}
|
||||
String(const value_type* s, size_type n): stl_string(s, n) {}
|
||||
String(const stl_string& s, size_type pos=0, size_type n=npos):
|
||||
stl_string(s, pos, n) {}
|
||||
String()
|
||||
: stl_string()
|
||||
{
|
||||
}
|
||||
String(const value_type* s)
|
||||
: stl_string(s)
|
||||
{
|
||||
}
|
||||
String(const value_type* s, size_type n)
|
||||
: stl_string(s, n)
|
||||
{
|
||||
}
|
||||
String(const stl_string& s, size_type pos = 0, size_type n = npos)
|
||||
: stl_string(s, pos, n)
|
||||
{
|
||||
}
|
||||
}; // End Class: String
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
inline bool operator<(String const& l, String const& r)
|
||||
{
|
||||
{
|
||||
return (static_cast<std::string const&>(l) <
|
||||
static_cast<std::string const&>(r));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
+80
-141
@@ -1,27 +1,18 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(System.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "System.h.in"
|
||||
#include "System.h.in"
|
||||
#endif
|
||||
|
||||
#include <ctype.h> /* isspace */
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memcpy */
|
||||
#include <ctype.h> /* isspace */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -32,28 +23,24 @@ typedef int kwsysSystem_ptrdiff_t;
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysSystem__AppendByte(char* local,
|
||||
char** begin, char** end,
|
||||
static int kwsysSystem__AppendByte(char* local, char** begin, char** end,
|
||||
int* size, char c)
|
||||
{
|
||||
/* Allocate space for the character. */
|
||||
if((*end - *begin) >= *size)
|
||||
{
|
||||
if ((*end - *begin) >= *size) {
|
||||
kwsysSystem_ptrdiff_t length = *end - *begin;
|
||||
char* newBuffer = (char*)malloc((size_t)(*size*2));
|
||||
if(!newBuffer)
|
||||
{
|
||||
char* newBuffer = (char*)malloc((size_t)(*size * 2));
|
||||
if (!newBuffer) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(newBuffer, *begin, (size_t)(length)*sizeof(char));
|
||||
if(*begin != local)
|
||||
{
|
||||
}
|
||||
memcpy(newBuffer, *begin, (size_t)(length) * sizeof(char));
|
||||
if (*begin != local) {
|
||||
free(*begin);
|
||||
}
|
||||
}
|
||||
*begin = newBuffer;
|
||||
*end = *begin + length;
|
||||
*size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the character. */
|
||||
*(*end)++ = c;
|
||||
@@ -61,47 +48,41 @@ static int kwsysSystem__AppendByte(char* local,
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int kwsysSystem__AppendArgument(char** local,
|
||||
char*** begin, char*** end,
|
||||
int* size,
|
||||
char* arg_local,
|
||||
static int kwsysSystem__AppendArgument(char** local, char*** begin,
|
||||
char*** end, int* size, char* arg_local,
|
||||
char** arg_begin, char** arg_end,
|
||||
int* arg_size)
|
||||
{
|
||||
/* Append a null-terminator to the argument string. */
|
||||
if(!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size, '\0'))
|
||||
{
|
||||
if (!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size,
|
||||
'\0')) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for the argument pointer. */
|
||||
if((*end - *begin) >= *size)
|
||||
{
|
||||
if ((*end - *begin) >= *size) {
|
||||
kwsysSystem_ptrdiff_t length = *end - *begin;
|
||||
char** newPointers = (char**)malloc((size_t)(*size)*2*sizeof(char*));
|
||||
if(!newPointers)
|
||||
{
|
||||
char** newPointers = (char**)malloc((size_t)(*size) * 2 * sizeof(char*));
|
||||
if (!newPointers) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(newPointers, *begin, (size_t)(length)*sizeof(char*));
|
||||
if(*begin != local)
|
||||
{
|
||||
}
|
||||
memcpy(newPointers, *begin, (size_t)(length) * sizeof(char*));
|
||||
if (*begin != local) {
|
||||
free(*begin);
|
||||
}
|
||||
}
|
||||
*begin = newPointers;
|
||||
*end = *begin + length;
|
||||
*size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for the argument string. */
|
||||
**end = (char*)malloc((size_t)(*arg_end - *arg_begin));
|
||||
if(!**end)
|
||||
{
|
||||
if (!**end) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the argument in the command array. */
|
||||
memcpy(**end, *arg_begin,(size_t)(*arg_end - *arg_begin));
|
||||
memcpy(**end, *arg_begin, (size_t)(*arg_end - *arg_begin));
|
||||
++(*end);
|
||||
|
||||
/* Reset the argument to be empty. */
|
||||
@@ -135,150 +116,109 @@ static char** kwsysSystem__ParseUnixCommand(const char* command, int flags)
|
||||
int in_single = 0;
|
||||
int in_double = 0;
|
||||
int failed = 0;
|
||||
for(;*c; ++c)
|
||||
{
|
||||
if(in_escape)
|
||||
{
|
||||
for (; *c; ++c) {
|
||||
if (in_escape) {
|
||||
/* This character is escaped so do no special handling. */
|
||||
if(!in_argument)
|
||||
{
|
||||
if (!in_argument) {
|
||||
in_argument = 1;
|
||||
}
|
||||
if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size, *c))
|
||||
{
|
||||
}
|
||||
if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end,
|
||||
&buffer_size, *c)) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
in_escape = 0;
|
||||
}
|
||||
else if(*c == '\\')
|
||||
{
|
||||
in_escape = 0;
|
||||
} else if (*c == '\\') {
|
||||
/* The next character should be escaped. */
|
||||
in_escape = 1;
|
||||
}
|
||||
else if(*c == '\'' && !in_double)
|
||||
{
|
||||
} else if (*c == '\'' && !in_double) {
|
||||
/* Enter or exit single-quote state. */
|
||||
if(in_single)
|
||||
{
|
||||
if (in_single) {
|
||||
in_single = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
in_single = 1;
|
||||
if(!in_argument)
|
||||
{
|
||||
if (!in_argument) {
|
||||
in_argument = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(*c == '"' && !in_single)
|
||||
{
|
||||
} else if (*c == '"' && !in_single) {
|
||||
/* Enter or exit double-quote state. */
|
||||
if(in_double)
|
||||
{
|
||||
if (in_double) {
|
||||
in_double = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
in_double = 1;
|
||||
if(!in_argument)
|
||||
{
|
||||
if (!in_argument) {
|
||||
in_argument = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(isspace((unsigned char) *c))
|
||||
{
|
||||
if(in_argument)
|
||||
{
|
||||
if(in_single || in_double)
|
||||
{
|
||||
} else if (isspace((unsigned char)*c)) {
|
||||
if (in_argument) {
|
||||
if (in_single || in_double) {
|
||||
/* This space belongs to a quoted argument. */
|
||||
if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size, *c))
|
||||
{
|
||||
if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size, *c)) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* This argument has been terminated by whitespace. */
|
||||
if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
|
||||
&pointer_end, &pointers_size,
|
||||
local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size))
|
||||
{
|
||||
if (!kwsysSystem__AppendArgument(
|
||||
local_pointers, &pointer_begin, &pointer_end, &pointers_size,
|
||||
local_buffer, &buffer_begin, &buffer_end, &buffer_size)) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
in_argument = 0;
|
||||
}
|
||||
in_argument = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* This character belong to an argument. */
|
||||
if(!in_argument)
|
||||
{
|
||||
if (!in_argument) {
|
||||
in_argument = 1;
|
||||
}
|
||||
if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size, *c))
|
||||
{
|
||||
}
|
||||
if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end,
|
||||
&buffer_size, *c)) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish the last argument. */
|
||||
if(in_argument)
|
||||
{
|
||||
if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
|
||||
&pointer_end, &pointers_size,
|
||||
local_buffer, &buffer_begin,
|
||||
&buffer_end, &buffer_size))
|
||||
{
|
||||
if (in_argument) {
|
||||
if (!kwsysSystem__AppendArgument(
|
||||
local_pointers, &pointer_begin, &pointer_end, &pointers_size,
|
||||
local_buffer, &buffer_begin, &buffer_end, &buffer_size)) {
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still have memory allocate space for the new command
|
||||
buffer. */
|
||||
if(!failed)
|
||||
{
|
||||
if (!failed) {
|
||||
kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
|
||||
newCommand = (char**)malloc((size_t)(n+1)*sizeof(char*));
|
||||
}
|
||||
newCommand = (char**)malloc((size_t)(n + 1) * sizeof(char*));
|
||||
}
|
||||
|
||||
if(newCommand)
|
||||
{
|
||||
if (newCommand) {
|
||||
/* Copy the arguments into the new command buffer. */
|
||||
kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
|
||||
memcpy(newCommand, pointer_begin, sizeof(char*)*(size_t)(n));
|
||||
memcpy(newCommand, pointer_begin, sizeof(char*) * (size_t)(n));
|
||||
newCommand[n] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Free arguments already allocated. */
|
||||
while(pointer_end != pointer_begin)
|
||||
{
|
||||
while (pointer_end != pointer_begin) {
|
||||
free(*(--pointer_end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free temporary buffers. */
|
||||
if(pointer_begin != local_pointers)
|
||||
{
|
||||
if (pointer_begin != local_pointers) {
|
||||
free(pointer_begin);
|
||||
}
|
||||
if(buffer_begin != local_buffer)
|
||||
{
|
||||
}
|
||||
if (buffer_begin != local_buffer) {
|
||||
free(buffer_begin);
|
||||
}
|
||||
}
|
||||
|
||||
/* The flags argument is currently unused. */
|
||||
(void)flags;
|
||||
@@ -291,10 +231,9 @@ static char** kwsysSystem__ParseUnixCommand(const char* command, int flags)
|
||||
char** kwsysSystem_Parse_CommandForUnix(const char* command, int flags)
|
||||
{
|
||||
/* Validate the flags. */
|
||||
if(flags != 0)
|
||||
{
|
||||
if (flags != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Forward to our internal implementation. */
|
||||
return kwsysSystem__ParseUnixCommand(command, flags);
|
||||
|
||||
+11
-21
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_System_h
|
||||
#define @KWSYS_NAMESPACE@_System_h
|
||||
|
||||
@@ -19,16 +10,15 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysSystem_Parse_CommandForUnix kwsys_ns(System_Parse_CommandForUnix)
|
||||
#define kwsysSystem_Parse_CommandForUnix kwsys_ns(System_Parse_CommandForUnix)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -59,11 +49,11 @@ kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysSystem_Parse_CommandForUnix
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysSystem_Parse_CommandForUnix
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+2179
-2156
File diff suppressed because it is too large.
Load diff
@@ -1,23 +1,14 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_SystemInformation_h
|
||||
#define @KWSYS_NAMESPACE@_SystemInformation_h
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <string>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
// forward declare the implementation class
|
||||
class SystemInformationImplementation;
|
||||
@@ -29,24 +20,24 @@ class @KWSYS_NAMESPACE@_EXPORT SystemInformation
|
||||
#elif @KWSYS_USE___INT64@
|
||||
typedef __int64 LongLong;
|
||||
#else
|
||||
# error "No Long Long"
|
||||
#error "No Long Long"
|
||||
#endif
|
||||
friend class SystemInformationImplementation;
|
||||
SystemInformationImplementation* Implementation;
|
||||
|
||||
public:
|
||||
SystemInformation();
|
||||
~SystemInformation();
|
||||
|
||||
SystemInformation ();
|
||||
~SystemInformation ();
|
||||
|
||||
const char * GetVendorString();
|
||||
const char * GetVendorID();
|
||||
const char* GetVendorString();
|
||||
const char* GetVendorID();
|
||||
std::string GetTypeID();
|
||||
std::string GetFamilyID();
|
||||
std::string GetModelID();
|
||||
std::string GetModelName();
|
||||
std::string GetSteppingCode();
|
||||
const char * GetExtendedProcessorName();
|
||||
const char * GetProcessorSerialNumber();
|
||||
const char* GetExtendedProcessorName();
|
||||
const char* GetProcessorSerialNumber();
|
||||
int GetProcessorCacheSize();
|
||||
unsigned int GetLogicalProcessorsPerPhysical();
|
||||
float GetProcessorClockFrequency();
|
||||
@@ -58,13 +49,13 @@ public:
|
||||
// on this system.
|
||||
std::string GetCPUDescription();
|
||||
|
||||
const char * GetHostname();
|
||||
const char* GetHostname();
|
||||
std::string GetFullyQualifiedDomainName();
|
||||
|
||||
const char * GetOSName();
|
||||
const char * GetOSRelease();
|
||||
const char * GetOSVersion();
|
||||
const char * GetOSPlatform();
|
||||
const char* GetOSName();
|
||||
const char* GetOSRelease();
|
||||
const char* GetOSVersion();
|
||||
const char* GetOSPlatform();
|
||||
|
||||
int GetOSIsWindows();
|
||||
int GetOSIsLinux();
|
||||
@@ -93,9 +84,8 @@ public:
|
||||
// returns an informative general description if the installed and
|
||||
// available ram on this system. See the GetHostMmeoryTotal, and
|
||||
// Get{Host,Proc}MemoryAvailable methods for more information.
|
||||
std::string GetMemoryDescription(
|
||||
const char *hostLimitEnvVarName=NULL,
|
||||
const char *procLimitEnvVarName=NULL);
|
||||
std::string GetMemoryDescription(const char* hostLimitEnvVarName = NULL,
|
||||
const char* procLimitEnvVarName = NULL);
|
||||
|
||||
// Retrieve amount of physical memory installed on the system in KiB
|
||||
// units.
|
||||
@@ -107,7 +97,7 @@ public:
|
||||
// parallel. The amount of memory reported may differ from the host
|
||||
// total if a host wide resource limit is applied. Such reource limits
|
||||
// are reported to us via an applicaiton specified environment variable.
|
||||
LongLong GetHostMemoryAvailable(const char *hostLimitEnvVarName=NULL);
|
||||
LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = NULL);
|
||||
|
||||
// Get total system RAM in units of KiB available to this process.
|
||||
// This may differ from the host available if a per-process resource
|
||||
@@ -115,9 +105,8 @@ public:
|
||||
// system via rlimit API. Resource limits that are not imposed via
|
||||
// rlimit API may be reported to us via an application specified
|
||||
// environment variable.
|
||||
LongLong GetProcMemoryAvailable(
|
||||
const char *hostLimitEnvVarName=NULL,
|
||||
const char *procLimitEnvVarName=NULL);
|
||||
LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = NULL,
|
||||
const char* procLimitEnvVarName = NULL);
|
||||
|
||||
// Get the system RAM used by all processes on the host, in units of KiB.
|
||||
LongLong GetHostMemoryUsed();
|
||||
@@ -132,14 +121,12 @@ public:
|
||||
// enable/disable stack trace signal handler. In order to
|
||||
// produce an informative stack trace the application should
|
||||
// be dynamically linked and compiled with debug symbols.
|
||||
static
|
||||
void SetStackTraceOnError(int enable);
|
||||
static void SetStackTraceOnError(int enable);
|
||||
|
||||
// format and return the current program stack in a string. In
|
||||
// order to produce an informative stack trace the application
|
||||
// should be dynamically linked and compiled with debug symbols.
|
||||
static
|
||||
std::string GetProgramStack(int firstFrame, int wholePath);
|
||||
static std::string GetProgramStack(int firstFrame, int wholePath);
|
||||
|
||||
/** Run the different checks */
|
||||
void RunCPUCheck();
|
||||
|
||||
+1608
-2337
File diff suppressed because it is too large.
Load diff
+133
-161
@@ -1,29 +1,20 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx
|
||||
#define @KWSYS_NAMESPACE@_SystemTools_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/String.hxx>
|
||||
|
||||
#include <sys/types.h>
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
# include <unistd.h> // For access permissions for use with access()
|
||||
#include <unistd.h> // For access permissions for use with access()
|
||||
#endif
|
||||
|
||||
// Required for va_list
|
||||
@@ -36,20 +27,18 @@
|
||||
// after stdarg.h does not solve things because we do not have control over
|
||||
// what the user does. This hack solves this problem by moving va_list to our
|
||||
// own namespace that is local for kwsys.
|
||||
namespace std {} // Required for platforms that do not have std namespace
|
||||
namespace @KWSYS_NAMESPACE@_VA_LIST
|
||||
{
|
||||
using namespace std;
|
||||
typedef va_list hack_va_list;
|
||||
namespace std {
|
||||
} // Required for platforms that do not have std namespace
|
||||
namespace @KWSYS_NAMESPACE@_VA_LIST {
|
||||
using namespace std;
|
||||
typedef va_list hack_va_list;
|
||||
}
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
|
||||
}
|
||||
#endif // va_list
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
class SystemToolsTranslationMap;
|
||||
class SystemToolsPathCaseMap;
|
||||
@@ -76,17 +65,17 @@ static SystemToolsManager SystemToolsManagerInstance;
|
||||
// combined using the | operator.
|
||||
typedef int TestFilePermissions;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
// On Windows (VC and Borland), no system header defines these constants...
|
||||
static const TestFilePermissions TEST_FILE_OK = 0;
|
||||
static const TestFilePermissions TEST_FILE_READ = 4;
|
||||
static const TestFilePermissions TEST_FILE_WRITE = 2;
|
||||
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
|
||||
// On Windows (VC and Borland), no system header defines these constants...
|
||||
static const TestFilePermissions TEST_FILE_OK = 0;
|
||||
static const TestFilePermissions TEST_FILE_READ = 4;
|
||||
static const TestFilePermissions TEST_FILE_WRITE = 2;
|
||||
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
|
||||
#else
|
||||
// Standard POSIX constants
|
||||
static const TestFilePermissions TEST_FILE_OK = F_OK;
|
||||
static const TestFilePermissions TEST_FILE_READ = R_OK;
|
||||
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
|
||||
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
|
||||
// Standard POSIX constants
|
||||
static const TestFilePermissions TEST_FILE_OK = F_OK;
|
||||
static const TestFilePermissions TEST_FILE_READ = R_OK;
|
||||
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
|
||||
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
|
||||
#endif
|
||||
|
||||
/** \class SystemTools
|
||||
@@ -95,7 +84,6 @@ typedef int TestFilePermissions;
|
||||
class @KWSYS_NAMESPACE@_EXPORT SystemTools
|
||||
{
|
||||
public:
|
||||
|
||||
/** -----------------------------------------------------------------
|
||||
* String Manipulation Routines
|
||||
* -----------------------------------------------------------------
|
||||
@@ -118,11 +106,9 @@ public:
|
||||
/**
|
||||
* Replace replace all occurences of the string in the source string.
|
||||
*/
|
||||
static void ReplaceString(std::string& source,
|
||||
const char* replace,
|
||||
static void ReplaceString(std::string& source, const char* replace,
|
||||
const char* with);
|
||||
static void ReplaceString(std::string& source,
|
||||
const std::string& replace,
|
||||
static void ReplaceString(std::string& source, const std::string& replace,
|
||||
const std::string& with);
|
||||
|
||||
/**
|
||||
@@ -162,7 +148,7 @@ public:
|
||||
* Remove some characters from a string.
|
||||
* Return a pointer to the new resulting string (allocated with 'new')
|
||||
*/
|
||||
static char* RemoveChars(const char* str, const char *toremove);
|
||||
static char* RemoveChars(const char* str, const char* toremove);
|
||||
|
||||
/**
|
||||
* Remove remove all but 0->9, A->F characters from a string.
|
||||
@@ -174,7 +160,8 @@ public:
|
||||
* Replace some characters by another character in a string (in-place)
|
||||
* Return a pointer to string
|
||||
*/
|
||||
static char* ReplaceChars(char* str, const char *toreplace,char replacement);
|
||||
static char* ReplaceChars(char* str, const char* toreplace,
|
||||
char replacement);
|
||||
|
||||
/**
|
||||
* Returns true if str1 starts (respectively ends) with str2
|
||||
@@ -200,41 +187,42 @@ public:
|
||||
* Return the string cropped to a given length by removing chars in the
|
||||
* center of the string and replacing them with an ellipsis (...)
|
||||
*/
|
||||
static std::string CropString(const std::string&,size_t max_len);
|
||||
static std::string CropString(const std::string&, size_t max_len);
|
||||
|
||||
/** split a path by separator into an array of strings, default is /.
|
||||
If isPath is true then the string is treated like a path and if
|
||||
s starts with a / then the first element of the returned array will
|
||||
be /, so /foo/bar will be [/, foo, bar]
|
||||
*/
|
||||
static std::vector<String> SplitString(const std::string& s, char separator = '/',
|
||||
bool isPath = false);
|
||||
static std::vector<String> SplitString(const std::string& s,
|
||||
char separator = '/',
|
||||
bool isPath = false);
|
||||
/**
|
||||
* Perform a case-independent string comparison
|
||||
*/
|
||||
static int Strucmp(const char *s1, const char *s2);
|
||||
static int Strucmp(const char* s1, const char* s2);
|
||||
|
||||
/**
|
||||
* Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
|
||||
* Return false on error, true on success
|
||||
*/
|
||||
static bool ConvertDateMacroString(const char *str, time_t *tmt);
|
||||
static bool ConvertTimeStampMacroString(const char *str, time_t *tmt);
|
||||
static bool ConvertDateMacroString(const char* str, time_t* tmt);
|
||||
static bool ConvertTimeStampMacroString(const char* str, time_t* tmt);
|
||||
|
||||
/**
|
||||
* Split a string on its newlines into multiple lines
|
||||
* Return false only if the last line stored had no newline
|
||||
*/
|
||||
static bool Split(const std::string& s, std::vector<std::string>& l);
|
||||
static bool Split(const std::string& s, std::vector<std::string>& l, char separator);
|
||||
static bool Split(const std::string& s, std::vector<std::string>& l,
|
||||
char separator);
|
||||
|
||||
/**
|
||||
* Return string with space added between capitalized words
|
||||
* (i.e. EatMyShorts becomes Eat My Shorts )
|
||||
* (note that IEatShorts becomes IEat Shorts)
|
||||
*/
|
||||
static std::string AddSpaceBetweenCapitalizedWords(
|
||||
const std::string&);
|
||||
static std::string AddSpaceBetweenCapitalizedWords(const std::string&);
|
||||
|
||||
/**
|
||||
* Append two or more strings and produce new one.
|
||||
@@ -242,10 +230,9 @@ public:
|
||||
* with 'new'.
|
||||
* Return 0 if inputs are empty or there was an error
|
||||
*/
|
||||
static char* AppendStrings(
|
||||
const char* str1, const char* str2);
|
||||
static char* AppendStrings(
|
||||
const char* str1, const char* str2, const char* str3);
|
||||
static char* AppendStrings(const char* str1, const char* str2);
|
||||
static char* AppendStrings(const char* str1, const char* str2,
|
||||
const char* str3);
|
||||
|
||||
/**
|
||||
* Estimate the length of the string that will be produced
|
||||
@@ -256,13 +243,13 @@ public:
|
||||
* you will not be able to use this 'ap' anymore from the beginning.
|
||||
* It's up to you to call va_end though.
|
||||
*/
|
||||
static int EstimateFormatLength(const char *format, va_list ap);
|
||||
static int EstimateFormatLength(const char* format, va_list ap);
|
||||
|
||||
/**
|
||||
* Escape specific characters in 'str'.
|
||||
*/
|
||||
static std::string EscapeChars(
|
||||
const char *str, const char *chars_to_escape, char escape_char = '\\');
|
||||
static std::string EscapeChars(const char* str, const char* chars_to_escape,
|
||||
char escape_char = '\\');
|
||||
|
||||
/** -----------------------------------------------------------------
|
||||
* Filename Manipulation Routines
|
||||
@@ -338,13 +325,13 @@ public:
|
||||
static bool TestFileAccess(const std::string& filename,
|
||||
TestFilePermissions permissions);
|
||||
|
||||
/**
|
||||
* Converts Cygwin path to Win32 path. Uses dictionary container for
|
||||
* caching and calls to cygwin_conv_to_win32_path from Cygwin dll
|
||||
* for actual translation. Returns true on success, else false.
|
||||
*/
|
||||
/**
|
||||
* Converts Cygwin path to Win32 path. Uses dictionary container for
|
||||
* caching and calls to cygwin_conv_to_win32_path from Cygwin dll
|
||||
* for actual translation. Returns true on success, else false.
|
||||
*/
|
||||
#ifdef __CYGWIN__
|
||||
static bool PathCygwinToWin32(const char *path, char *win32_path);
|
||||
static bool PathCygwinToWin32(const char* path, char* win32_path);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -363,8 +350,7 @@ public:
|
||||
* When true is returned, result has -1, 0, +1 for
|
||||
* f1 older, same, or newer than f2.
|
||||
*/
|
||||
static bool FileTimeCompare(const std::string& f1,
|
||||
const std::string& f2,
|
||||
static bool FileTimeCompare(const std::string& f1, const std::string& f2,
|
||||
int* result);
|
||||
|
||||
/**
|
||||
@@ -388,10 +374,8 @@ public:
|
||||
* part, the empty string is returned.
|
||||
*/
|
||||
static std::string GetProgramPath(const std::string&);
|
||||
static bool SplitProgramPath(const std::string& in_name,
|
||||
std::string& dir,
|
||||
std::string& file,
|
||||
bool errorReport = true);
|
||||
static bool SplitProgramPath(const std::string& in_name, std::string& dir,
|
||||
std::string& file, bool errorReport = true);
|
||||
|
||||
/**
|
||||
* Given argv[0] for a unix program find the full path to a running
|
||||
@@ -405,10 +389,8 @@ public:
|
||||
* buildDir is a possibly null path to the build directory.
|
||||
* installPrefix is a possibly null pointer to the install directory.
|
||||
*/
|
||||
static bool FindProgramPath(const char* argv0,
|
||||
std::string& pathOut,
|
||||
std::string& errorMsg,
|
||||
const char* exeName = 0,
|
||||
static bool FindProgramPath(const char* argv0, std::string& pathOut,
|
||||
std::string& errorMsg, const char* exeName = 0,
|
||||
const char* buildDir = 0,
|
||||
const char* installPrefix = 0);
|
||||
|
||||
@@ -420,9 +402,9 @@ public:
|
||||
*/
|
||||
static std::string CollapseFullPath(const std::string& in_relative);
|
||||
static std::string CollapseFullPath(const std::string& in_relative,
|
||||
const char* in_base);
|
||||
const char* in_base);
|
||||
static std::string CollapseFullPath(const std::string& in_relative,
|
||||
const std::string& in_base);
|
||||
const std::string& in_base);
|
||||
|
||||
/**
|
||||
* Get the real path for a given path, removing all symlinks. In
|
||||
@@ -432,7 +414,7 @@ public:
|
||||
* contains error description.
|
||||
*/
|
||||
static std::string GetRealPath(const std::string& path,
|
||||
std::string* errorMessage = 0);
|
||||
std::string* errorMessage = 0);
|
||||
|
||||
/**
|
||||
* Split a path name into its root component and the rest of the
|
||||
@@ -450,7 +432,7 @@ public:
|
||||
* given.
|
||||
*/
|
||||
static const char* SplitPathRootComponent(const std::string& p,
|
||||
std::string* root=0);
|
||||
std::string* root = 0);
|
||||
|
||||
/**
|
||||
* Split a path name into its basic components. The first component
|
||||
@@ -470,18 +452,15 @@ public:
|
||||
* Join components of a path name into a single string. See
|
||||
* SplitPath for the format of the components.
|
||||
*/
|
||||
static std::string JoinPath(
|
||||
const std::vector<std::string>& components);
|
||||
static std::string JoinPath(
|
||||
std::vector<std::string>::const_iterator first,
|
||||
std::vector<std::string>::const_iterator last);
|
||||
static std::string JoinPath(const std::vector<std::string>& components);
|
||||
static std::string JoinPath(std::vector<std::string>::const_iterator first,
|
||||
std::vector<std::string>::const_iterator last);
|
||||
|
||||
/**
|
||||
* Compare a path or components of a path.
|
||||
*/
|
||||
static bool ComparePath(const std::string& c1, const std::string& c2);
|
||||
|
||||
|
||||
/**
|
||||
* Return path of a full filename (no trailing slashes)
|
||||
*/
|
||||
@@ -495,9 +474,8 @@ public:
|
||||
/**
|
||||
* Split a program from its arguments and handle spaces in the paths
|
||||
*/
|
||||
static void SplitProgramFromArgs(
|
||||
const std::string& path,
|
||||
std::string& program, std::string& args);
|
||||
static void SplitProgramFromArgs(const std::string& path,
|
||||
std::string& program, std::string& args);
|
||||
|
||||
/**
|
||||
* Return longest file extension of a full filename (dot included)
|
||||
@@ -507,20 +485,17 @@ public:
|
||||
/**
|
||||
* Return shortest file extension of a full filename (dot included)
|
||||
*/
|
||||
static std::string GetFilenameLastExtension(
|
||||
const std::string& filename);
|
||||
static std::string GetFilenameLastExtension(const std::string& filename);
|
||||
|
||||
/**
|
||||
* Return file name without extension of a full filename
|
||||
*/
|
||||
static std::string GetFilenameWithoutExtension(
|
||||
const std::string&);
|
||||
static std::string GetFilenameWithoutExtension(const std::string&);
|
||||
|
||||
/**
|
||||
* Return file name without its last (shortest) extension
|
||||
*/
|
||||
static std::string GetFilenameWithoutLastExtension(
|
||||
const std::string&);
|
||||
static std::string GetFilenameWithoutLastExtension(const std::string&);
|
||||
|
||||
/**
|
||||
* Return whether the path represents a full path (not relative)
|
||||
@@ -541,10 +516,8 @@ public:
|
||||
* end-of-file was reached. If the has_newline argument is specified, it will
|
||||
* be true when the line read had a newline character.
|
||||
*/
|
||||
static bool GetLineFromStream(std::istream& istr,
|
||||
std::string& line,
|
||||
bool* has_newline=0,
|
||||
long sizeLimit=-1);
|
||||
static bool GetLineFromStream(std::istream& istr, std::string& line,
|
||||
bool* has_newline = 0, long sizeLimit = -1);
|
||||
|
||||
/**
|
||||
* Get the parent directory of the directory or file
|
||||
@@ -554,7 +527,8 @@ public:
|
||||
/**
|
||||
* Check if the given file or directory is in subdirectory of dir
|
||||
*/
|
||||
static bool IsSubDirectory(const std::string& fileOrDir, const std::string& dir);
|
||||
static bool IsSubDirectory(const std::string& fileOrDir,
|
||||
const std::string& dir);
|
||||
|
||||
/** -----------------------------------------------------------------
|
||||
* File Manipulation Routines
|
||||
@@ -584,7 +558,8 @@ public:
|
||||
/**
|
||||
* Compare the contents of two files. Return true if different
|
||||
*/
|
||||
static bool FilesDiffer(const std::string& source, const std::string& destination);
|
||||
static bool FilesDiffer(const std::string& source,
|
||||
const std::string& destination);
|
||||
|
||||
/**
|
||||
* Return true if the two files are the same file
|
||||
@@ -594,15 +569,16 @@ public:
|
||||
/**
|
||||
* Copy a file.
|
||||
*/
|
||||
static bool CopyFileAlways(const std::string& source, const std::string& destination);
|
||||
static bool CopyFileAlways(const std::string& source,
|
||||
const std::string& destination);
|
||||
|
||||
/**
|
||||
* Copy a file. If the "always" argument is true the file is always
|
||||
* copied. If it is false, the file is copied only if it is new or
|
||||
* has changed.
|
||||
*/
|
||||
static bool CopyAFile(const std::string& source, const std::string& destination,
|
||||
bool always = true);
|
||||
static bool CopyAFile(const std::string& source,
|
||||
const std::string& destination, bool always = true);
|
||||
|
||||
/**
|
||||
* Copy content directory to another directory with all files and
|
||||
@@ -610,7 +586,8 @@ public:
|
||||
* always copied. If it is false, only files that have changed or
|
||||
* are new are copied.
|
||||
*/
|
||||
static bool CopyADirectory(const std::string& source, const std::string& destination,
|
||||
static bool CopyADirectory(const std::string& source,
|
||||
const std::string& destination,
|
||||
bool always = true);
|
||||
|
||||
/**
|
||||
@@ -633,8 +610,7 @@ public:
|
||||
*/
|
||||
static std::string FindFile(
|
||||
const std::string& name,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
|
||||
/**
|
||||
@@ -642,8 +618,7 @@ public:
|
||||
*/
|
||||
static std::string FindDirectory(
|
||||
const std::string& name,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
|
||||
/**
|
||||
@@ -651,26 +626,22 @@ public:
|
||||
*/
|
||||
static std::string FindProgram(
|
||||
const char* name,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
static std::string FindProgram(
|
||||
const std::string& name,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
static std::string FindProgram(
|
||||
const std::vector<std::string>& names,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
|
||||
/**
|
||||
* Find a library in the system PATH, with optional extra paths
|
||||
*/
|
||||
static std::string FindLibrary(
|
||||
const std::string& name,
|
||||
const std::vector<std::string>& path);
|
||||
static std::string FindLibrary(const std::string& name,
|
||||
const std::vector<std::string>& path);
|
||||
|
||||
/**
|
||||
* Return true if the file is a directory
|
||||
@@ -685,8 +656,8 @@ public:
|
||||
/**
|
||||
* Return true if the file has a given signature (first set of bytes)
|
||||
*/
|
||||
static bool FileHasSignature(
|
||||
const char* filename, const char *signature, long offset = 0);
|
||||
static bool FileHasSignature(const char* filename, const char* signature,
|
||||
long offset = 0);
|
||||
|
||||
/**
|
||||
* Attempt to detect and return the type of a file.
|
||||
@@ -703,16 +674,16 @@ public:
|
||||
FileTypeBinary,
|
||||
FileTypeText
|
||||
};
|
||||
static SystemTools::FileTypeEnum DetectFileType(
|
||||
const char* filename,
|
||||
unsigned long length = 256,
|
||||
double percent_bin = 0.05);
|
||||
static SystemTools::FileTypeEnum DetectFileType(const char* filename,
|
||||
unsigned long length = 256,
|
||||
double percent_bin = 0.05);
|
||||
|
||||
/**
|
||||
* Create a symbolic link if the platform supports it. Returns whether
|
||||
* creation succeeded.
|
||||
*/
|
||||
static bool CreateSymlink(const std::string& origName, const std::string& newName);
|
||||
static bool CreateSymlink(const std::string& origName,
|
||||
const std::string& newName);
|
||||
|
||||
/**
|
||||
* Read the contents of a symbolic link. Returns whether reading
|
||||
@@ -735,8 +706,7 @@ public:
|
||||
* etc.
|
||||
* Return true if the file was found, false otherwise.
|
||||
*/
|
||||
static bool LocateFileInDir(const char *filename,
|
||||
const char *dir,
|
||||
static bool LocateFileInDir(const char* filename, const char* dir,
|
||||
std::string& filename_found,
|
||||
int try_filename_dirs = 0);
|
||||
|
||||
@@ -748,7 +718,8 @@ public:
|
||||
/a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
|
||||
from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
|
||||
*/
|
||||
static std::string RelativePath(const std::string& local, const std::string& remote);
|
||||
static std::string RelativePath(const std::string& local,
|
||||
const std::string& remote);
|
||||
|
||||
/**
|
||||
* Return file's modified time
|
||||
@@ -760,12 +731,12 @@ 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 )
|
||||
/**
|
||||
* Visual C++ does not define mode_t (note that Borland does, however).
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get and set permissions of the file. If honor_umask is set, the umask
|
||||
@@ -777,8 +748,10 @@ public:
|
||||
*/
|
||||
static bool GetPermissions(const char* file, mode_t& mode);
|
||||
static bool GetPermissions(const std::string& file, mode_t& mode);
|
||||
static bool SetPermissions(const char* file, mode_t mode, bool honor_umask = false);
|
||||
static bool SetPermissions(const std::string& file, mode_t mode, bool honor_umask = false);
|
||||
static bool SetPermissions(const char* file, mode_t mode,
|
||||
bool honor_umask = false);
|
||||
static bool SetPermissions(const std::string& file, mode_t mode,
|
||||
bool honor_umask = false);
|
||||
|
||||
/** -----------------------------------------------------------------
|
||||
* Time Manipulation Routines
|
||||
@@ -803,7 +776,12 @@ public:
|
||||
* registry values. The default is to match the currently running
|
||||
* binary type.
|
||||
*/
|
||||
enum KeyWOW64 { KeyWOW64_Default, KeyWOW64_32, KeyWOW64_64 };
|
||||
enum KeyWOW64
|
||||
{
|
||||
KeyWOW64_Default,
|
||||
KeyWOW64_32,
|
||||
KeyWOW64_64
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of subkeys.
|
||||
@@ -815,13 +793,14 @@ public:
|
||||
/**
|
||||
* Read a registry value
|
||||
*/
|
||||
static bool ReadRegistryValue(const std::string& key, std::string &value,
|
||||
static bool ReadRegistryValue(const std::string& key, std::string& value,
|
||||
KeyWOW64 view = KeyWOW64_Default);
|
||||
|
||||
/**
|
||||
* Write a registry value
|
||||
*/
|
||||
static bool WriteRegistryValue(const std::string& key, const std::string& value,
|
||||
static bool WriteRegistryValue(const std::string& key,
|
||||
const std::string& value,
|
||||
KeyWOW64 view = KeyWOW64_Default);
|
||||
|
||||
/**
|
||||
@@ -840,8 +819,7 @@ public:
|
||||
* string vector passed in. If env is set then the value
|
||||
* of env will be used instead of PATH.
|
||||
*/
|
||||
static void GetPath(std::vector<std::string>& path,
|
||||
const char* env=0);
|
||||
static void GetPath(std::vector<std::string>& path, const char* env = 0);
|
||||
|
||||
/**
|
||||
* Read an environment variable
|
||||
@@ -864,7 +842,7 @@ public:
|
||||
/**
|
||||
* Get current working directory CWD
|
||||
*/
|
||||
static std::string GetCurrentWorkingDirectory(bool collapse =true);
|
||||
static std::string GetCurrentWorkingDirectory(bool collapse = true);
|
||||
|
||||
/**
|
||||
* Change directory to the directory specified
|
||||
@@ -893,7 +871,8 @@ public:
|
||||
/**
|
||||
* Add an entry in the path translation table.
|
||||
*/
|
||||
static void AddTranslationPath(const std::string& dir, const std::string& refdir);
|
||||
static void AddTranslationPath(const std::string& dir,
|
||||
const std::string& refdir);
|
||||
|
||||
/**
|
||||
* If dir is different after CollapseFullPath is called,
|
||||
@@ -904,7 +883,7 @@ public:
|
||||
/**
|
||||
* Update path by going through the Path Translation table;
|
||||
*/
|
||||
static void CheckTranslationPath(std::string & path);
|
||||
static void CheckTranslationPath(std::string& path);
|
||||
|
||||
/**
|
||||
* Delay the execution for a specified amount of time specified
|
||||
@@ -929,9 +908,8 @@ public:
|
||||
* and fill protocol as appropriate.
|
||||
* Return false if the URL does not have the required form, true otherwise.
|
||||
*/
|
||||
static bool ParseURLProtocol( const std::string& URL,
|
||||
std::string& protocol,
|
||||
std::string& dataglom );
|
||||
static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
|
||||
std::string& dataglom);
|
||||
|
||||
/**
|
||||
* Parse a string (a URL without protocol prefix) with the form:
|
||||
@@ -940,13 +918,10 @@ public:
|
||||
* when values are found.
|
||||
* Return true if the string matches the format; false otherwise.
|
||||
*/
|
||||
static bool ParseURL( const std::string& URL,
|
||||
std::string& protocol,
|
||||
std::string& username,
|
||||
std::string& password,
|
||||
std::string& hostname,
|
||||
std::string& dataport,
|
||||
std::string& datapath );
|
||||
static bool ParseURL(const std::string& URL, std::string& protocol,
|
||||
std::string& username, std::string& password,
|
||||
std::string& hostname, std::string& dataport,
|
||||
std::string& datapath);
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -963,17 +938,15 @@ private:
|
||||
* This method prevents warning on SGI
|
||||
*/
|
||||
SystemToolsManager* GetSystemToolsManager()
|
||||
{
|
||||
{
|
||||
return &SystemToolsManagerInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual implementation of ReplaceString.
|
||||
*/
|
||||
static void ReplaceString(std::string& source,
|
||||
const char* replace,
|
||||
size_t replaceSize,
|
||||
const std::string& with);
|
||||
static void ReplaceString(std::string& source, const char* replace,
|
||||
size_t replaceSize, const std::string& with);
|
||||
|
||||
/**
|
||||
* Actual implementation of FileIsFullPath.
|
||||
@@ -986,8 +959,7 @@ private:
|
||||
*/
|
||||
static std::string FindName(
|
||||
const std::string& name,
|
||||
const std::vector<std::string>& path =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string>& path = std::vector<std::string>(),
|
||||
bool no_system_path = false);
|
||||
|
||||
static const char* GetEnvImpl(const char* key);
|
||||
@@ -996,13 +968,13 @@ private:
|
||||
* Path translation table from dir to refdir
|
||||
* Each time 'dir' will be found it will be replace by 'refdir'
|
||||
*/
|
||||
static SystemToolsTranslationMap *TranslationMap;
|
||||
static SystemToolsTranslationMap* TranslationMap;
|
||||
#ifdef _WIN32
|
||||
static SystemToolsPathCaseMap *PathCaseMap;
|
||||
static SystemToolsEnvMap *EnvMap;
|
||||
static SystemToolsPathCaseMap* PathCaseMap;
|
||||
static SystemToolsEnvMap* EnvMap;
|
||||
#endif
|
||||
#ifdef __CYGWIN__
|
||||
static SystemToolsTranslationMap *Cyg2Win32Map;
|
||||
static SystemToolsTranslationMap* Cyg2Win32Map;
|
||||
#endif
|
||||
friend class SystemToolsManager;
|
||||
};
|
||||
|
||||
+141
-176
@@ -1,48 +1,39 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Terminal.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Terminal.h.in"
|
||||
#include "Terminal.h.in"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Configure support for this platform. */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define KWSYS_TERMINAL_SUPPORT_CONSOLE
|
||||
#define KWSYS_TERMINAL_SUPPORT_CONSOLE
|
||||
#endif
|
||||
#if !defined(_WIN32)
|
||||
# define KWSYS_TERMINAL_ISATTY_WORKS
|
||||
#define KWSYS_TERMINAL_ISATTY_WORKS
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Include needed system APIs. */
|
||||
|
||||
#include <stdarg.h> /* va_list */
|
||||
#include <stdlib.h> /* getenv */
|
||||
#include <string.h> /* strcmp */
|
||||
#include <stdarg.h> /* va_list */
|
||||
|
||||
#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
|
||||
# include <windows.h> /* SetConsoleTextAttribute */
|
||||
# include <io.h> /* _get_osfhandle */
|
||||
#include <io.h> /* _get_osfhandle */
|
||||
#include <windows.h> /* SetConsoleTextAttribute */
|
||||
#endif
|
||||
|
||||
#if defined(KWSYS_TERMINAL_ISATTY_WORKS)
|
||||
# include <unistd.h> /* isatty */
|
||||
#include <unistd.h> /* isatty */
|
||||
#else
|
||||
# include <sys/stat.h> /* fstat */
|
||||
#include <sys/stat.h> /* fstat */
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -53,8 +44,7 @@ static void kwsysTerminalSetVT100Color(FILE* stream, int color);
|
||||
static HANDLE kwsysTerminalGetStreamHandle(FILE* stream);
|
||||
static void kwsysTerminalSetConsoleColor(HANDLE hOut,
|
||||
CONSOLE_SCREEN_BUFFER_INFO* hOutInfo,
|
||||
FILE* stream,
|
||||
int color);
|
||||
FILE* stream, int color);
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -68,39 +58,35 @@ void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...)
|
||||
#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
|
||||
CONSOLE_SCREEN_BUFFER_INFO hOutInfo;
|
||||
HANDLE hOut = kwsysTerminalGetStreamHandle(stream);
|
||||
if(GetConsoleScreenBufferInfo(hOut, &hOutInfo))
|
||||
{
|
||||
if (GetConsoleScreenBufferInfo(hOut, &hOutInfo)) {
|
||||
pipeIsConsole = 1;
|
||||
kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream, color);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!pipeIsConsole && kwsysTerminalStreamIsVT100(stream,
|
||||
default_vt100, default_tty))
|
||||
{
|
||||
if (!pipeIsConsole &&
|
||||
kwsysTerminalStreamIsVT100(stream, default_vt100, default_tty)) {
|
||||
pipeIsVT100 = 1;
|
||||
kwsysTerminalSetVT100Color(stream, color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Format the text into the stream. */
|
||||
{
|
||||
va_list var_args;
|
||||
va_start(var_args, format);
|
||||
vfprintf(stream, format, var_args);
|
||||
va_end(var_args);
|
||||
va_list var_args;
|
||||
va_start(var_args, format);
|
||||
vfprintf(stream, format, var_args);
|
||||
va_end(var_args);
|
||||
}
|
||||
|
||||
/* Restore the normal color state for the stream. */
|
||||
/* Restore the normal color state for the stream. */
|
||||
#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
|
||||
if(pipeIsConsole)
|
||||
{
|
||||
if (pipeIsConsole) {
|
||||
kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream,
|
||||
kwsysTerminal_Color_Normal);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(pipeIsVT100)
|
||||
{
|
||||
if (pipeIsVT100) {
|
||||
kwsysTerminalSetVT100Color(stream, kwsysTerminal_Color_Normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -111,73 +97,68 @@ static int kwsysTerminalStreamIsNotInteractive(FILE* stream)
|
||||
/* The given stream is definitely not interactive if it is a regular
|
||||
file. */
|
||||
struct stat stream_stat;
|
||||
if(fstat(fileno(stream), &stream_stat) == 0)
|
||||
{
|
||||
if(stream_stat.st_mode & S_IFREG)
|
||||
{
|
||||
if (fstat(fileno(stream), &stream_stat) == 0) {
|
||||
if (stream_stat.st_mode & S_IFREG) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* List of terminal names known to support VT100 color escape sequences. */
|
||||
static const char* kwsysTerminalVT100Names[] =
|
||||
{
|
||||
"Eterm",
|
||||
"ansi",
|
||||
"color-xterm",
|
||||
"con132x25",
|
||||
"con132x30",
|
||||
"con132x43",
|
||||
"con132x60",
|
||||
"con80x25",
|
||||
"con80x28",
|
||||
"con80x30",
|
||||
"con80x43",
|
||||
"con80x50",
|
||||
"con80x60",
|
||||
"cons25",
|
||||
"console",
|
||||
"cygwin",
|
||||
"dtterm",
|
||||
"eterm-color",
|
||||
"gnome",
|
||||
"gnome-256color",
|
||||
"konsole",
|
||||
"konsole-256color",
|
||||
"kterm",
|
||||
"linux",
|
||||
"msys",
|
||||
"linux-c",
|
||||
"mach-color",
|
||||
"mlterm",
|
||||
"putty",
|
||||
"putty-256color",
|
||||
"rxvt",
|
||||
"rxvt-256color",
|
||||
"rxvt-cygwin",
|
||||
"rxvt-cygwin-native",
|
||||
"rxvt-unicode",
|
||||
"rxvt-unicode-256color",
|
||||
"screen",
|
||||
"screen-256color",
|
||||
"screen-256color-bce",
|
||||
"screen-bce",
|
||||
"screen-w",
|
||||
"screen.linux",
|
||||
"vt100",
|
||||
"xterm",
|
||||
"xterm-16color",
|
||||
"xterm-256color",
|
||||
"xterm-88color",
|
||||
"xterm-color",
|
||||
"xterm-debian",
|
||||
"xterm-termite",
|
||||
0
|
||||
};
|
||||
static const char* kwsysTerminalVT100Names[] = { "Eterm",
|
||||
"ansi",
|
||||
"color-xterm",
|
||||
"con132x25",
|
||||
"con132x30",
|
||||
"con132x43",
|
||||
"con132x60",
|
||||
"con80x25",
|
||||
"con80x28",
|
||||
"con80x30",
|
||||
"con80x43",
|
||||
"con80x50",
|
||||
"con80x60",
|
||||
"cons25",
|
||||
"console",
|
||||
"cygwin",
|
||||
"dtterm",
|
||||
"eterm-color",
|
||||
"gnome",
|
||||
"gnome-256color",
|
||||
"konsole",
|
||||
"konsole-256color",
|
||||
"kterm",
|
||||
"linux",
|
||||
"msys",
|
||||
"linux-c",
|
||||
"mach-color",
|
||||
"mlterm",
|
||||
"putty",
|
||||
"putty-256color",
|
||||
"rxvt",
|
||||
"rxvt-256color",
|
||||
"rxvt-cygwin",
|
||||
"rxvt-cygwin-native",
|
||||
"rxvt-unicode",
|
||||
"rxvt-unicode-256color",
|
||||
"screen",
|
||||
"screen-256color",
|
||||
"screen-256color-bce",
|
||||
"screen-bce",
|
||||
"screen-w",
|
||||
"screen.linux",
|
||||
"vt100",
|
||||
"xterm",
|
||||
"xterm-16color",
|
||||
"xterm-256color",
|
||||
"xterm-88color",
|
||||
"xterm-color",
|
||||
"xterm-debian",
|
||||
"xterm-termite",
|
||||
0 };
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Detect whether a stream is displayed in a VT100-compatible terminal. */
|
||||
@@ -186,10 +167,10 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
|
||||
{
|
||||
/* Force color according to http://bixense.com/clicolors/ convention. */
|
||||
{
|
||||
const char* clicolor_force = getenv("CLICOLOR_FORCE");
|
||||
if (clicolor_force && *clicolor_force && strcmp(clicolor_force, "0") != 0)
|
||||
{
|
||||
return 1;
|
||||
const char* clicolor_force = getenv("CLICOLOR_FORCE");
|
||||
if (clicolor_force && *clicolor_force &&
|
||||
strcmp(clicolor_force, "0") != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,38 +178,34 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
|
||||
seem to claim the TERM is xterm even though they do not support
|
||||
VT100 escapes. */
|
||||
{
|
||||
const char* emacs = getenv("EMACS");
|
||||
if(emacs && *emacs == 't')
|
||||
{
|
||||
return 0;
|
||||
const char* emacs = getenv("EMACS");
|
||||
if (emacs && *emacs == 't') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for a valid terminal. */
|
||||
if(!default_vt100)
|
||||
{
|
||||
if (!default_vt100) {
|
||||
const char** t = 0;
|
||||
const char* term = getenv("TERM");
|
||||
if(term)
|
||||
{
|
||||
for(t = kwsysTerminalVT100Names; *t && strcmp(term, *t) != 0; ++t) {}
|
||||
}
|
||||
if(!(t && *t))
|
||||
{
|
||||
return 0;
|
||||
if (term) {
|
||||
for (t = kwsysTerminalVT100Names; *t && strcmp(term, *t) != 0; ++t) {
|
||||
}
|
||||
}
|
||||
if (!(t && *t)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(KWSYS_TERMINAL_ISATTY_WORKS)
|
||||
/* Make sure the stream is a tty. */
|
||||
(void)default_tty;
|
||||
return isatty(fileno(stream))? 1:0;
|
||||
return isatty(fileno(stream)) ? 1 : 0;
|
||||
#else
|
||||
/* Check for cases in which the stream is definitely not a tty. */
|
||||
if(kwsysTerminalStreamIsNotInteractive(stream))
|
||||
{
|
||||
if (kwsysTerminalStreamIsNotInteractive(stream)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the provided default for whether this is a tty. */
|
||||
return default_tty;
|
||||
@@ -237,40 +214,38 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* VT100 escape sequence strings. */
|
||||
#define KWSYS_TERMINAL_VT100_NORMAL "\33[0m"
|
||||
#define KWSYS_TERMINAL_VT100_BOLD "\33[1m"
|
||||
#define KWSYS_TERMINAL_VT100_UNDERLINE "\33[4m"
|
||||
#define KWSYS_TERMINAL_VT100_BLINK "\33[5m"
|
||||
#define KWSYS_TERMINAL_VT100_INVERSE "\33[7m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_BLACK "\33[30m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_RED "\33[31m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_GREEN "\33[32m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW "\33[33m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_BLUE "\33[34m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA "\33[35m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_CYAN "\33[36m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_WHITE "\33[37m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_BLACK "\33[40m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_RED "\33[41m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_GREEN "\33[42m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW "\33[43m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_BLUE "\33[44m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA "\33[45m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_CYAN "\33[46m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_WHITE "\33[47m"
|
||||
#define KWSYS_TERMINAL_VT100_NORMAL "\33[0m"
|
||||
#define KWSYS_TERMINAL_VT100_BOLD "\33[1m"
|
||||
#define KWSYS_TERMINAL_VT100_UNDERLINE "\33[4m"
|
||||
#define KWSYS_TERMINAL_VT100_BLINK "\33[5m"
|
||||
#define KWSYS_TERMINAL_VT100_INVERSE "\33[7m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_BLACK "\33[30m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_RED "\33[31m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_GREEN "\33[32m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW "\33[33m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_BLUE "\33[34m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA "\33[35m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_CYAN "\33[36m"
|
||||
#define KWSYS_TERMINAL_VT100_FOREGROUND_WHITE "\33[37m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_BLACK "\33[40m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_RED "\33[41m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_GREEN "\33[42m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW "\33[43m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_BLUE "\33[44m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA "\33[45m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_CYAN "\33[46m"
|
||||
#define KWSYS_TERMINAL_VT100_BACKGROUND_WHITE "\33[47m"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Write VT100 escape sequences to the stream for the given color. */
|
||||
static void kwsysTerminalSetVT100Color(FILE* stream, int color)
|
||||
{
|
||||
if(color == kwsysTerminal_Color_Normal)
|
||||
{
|
||||
if (color == kwsysTerminal_Color_Normal) {
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(color & kwsysTerminal_Color_ForegroundMask)
|
||||
{
|
||||
switch (color & kwsysTerminal_Color_ForegroundMask) {
|
||||
case kwsysTerminal_Color_Normal:
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL);
|
||||
break;
|
||||
@@ -298,9 +273,8 @@ static void kwsysTerminalSetVT100Color(FILE* stream, int color)
|
||||
case kwsysTerminal_Color_ForegroundWhite:
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_WHITE);
|
||||
break;
|
||||
}
|
||||
switch(color & kwsysTerminal_Color_BackgroundMask)
|
||||
{
|
||||
}
|
||||
switch (color & kwsysTerminal_Color_BackgroundMask) {
|
||||
case kwsysTerminal_Color_BackgroundBlack:
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_BLACK);
|
||||
break;
|
||||
@@ -325,19 +299,18 @@ static void kwsysTerminalSetVT100Color(FILE* stream, int color)
|
||||
case kwsysTerminal_Color_BackgroundWhite:
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_WHITE);
|
||||
break;
|
||||
}
|
||||
if(color & kwsysTerminal_Color_ForegroundBold)
|
||||
{
|
||||
}
|
||||
if (color & kwsysTerminal_Color_ForegroundBold) {
|
||||
fprintf(stream, KWSYS_TERMINAL_VT100_BOLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
|
||||
|
||||
# define KWSYS_TERMINAL_MASK_FOREGROUND \
|
||||
#define KWSYS_TERMINAL_MASK_FOREGROUND \
|
||||
(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
|
||||
# define KWSYS_TERMINAL_MASK_BACKGROUND \
|
||||
#define KWSYS_TERMINAL_MASK_BACKGROUND \
|
||||
(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
|
||||
|
||||
/* Get the Windows handle for a FILE stream. */
|
||||
@@ -346,19 +319,16 @@ static HANDLE kwsysTerminalGetStreamHandle(FILE* stream)
|
||||
/* Get the C-library file descriptor from the stream. */
|
||||
int fd = fileno(stream);
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
#if defined(__CYGWIN__)
|
||||
/* Cygwin seems to have an extra pipe level. If the file descriptor
|
||||
corresponds to stdout or stderr then obtain the matching windows
|
||||
handle directly. */
|
||||
if(fd == fileno(stdout))
|
||||
{
|
||||
if (fd == fileno(stdout)) {
|
||||
return GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
else if(fd == fileno(stderr))
|
||||
{
|
||||
} else if (fd == fileno(stderr)) {
|
||||
return GetStdHandle(STD_ERROR_HANDLE);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the underlying Windows handle for the descriptor. */
|
||||
return (HANDLE)_get_osfhandle(fd);
|
||||
@@ -367,12 +337,10 @@ static HANDLE kwsysTerminalGetStreamHandle(FILE* stream)
|
||||
/* Set color attributes in a Windows console. */
|
||||
static void kwsysTerminalSetConsoleColor(HANDLE hOut,
|
||||
CONSOLE_SCREEN_BUFFER_INFO* hOutInfo,
|
||||
FILE* stream,
|
||||
int color)
|
||||
FILE* stream, int color)
|
||||
{
|
||||
WORD attributes = 0;
|
||||
switch(color & kwsysTerminal_Color_ForegroundMask)
|
||||
{
|
||||
switch (color & kwsysTerminal_Color_ForegroundMask) {
|
||||
case kwsysTerminal_Color_Normal:
|
||||
attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_FOREGROUND;
|
||||
break;
|
||||
@@ -400,9 +368,8 @@ static void kwsysTerminalSetConsoleColor(HANDLE hOut,
|
||||
case kwsysTerminal_Color_ForegroundWhite:
|
||||
attributes |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
||||
break;
|
||||
}
|
||||
switch(color & kwsysTerminal_Color_BackgroundMask)
|
||||
{
|
||||
}
|
||||
switch (color & kwsysTerminal_Color_BackgroundMask) {
|
||||
case kwsysTerminal_Color_Normal:
|
||||
attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_BACKGROUND;
|
||||
break;
|
||||
@@ -430,15 +397,13 @@ static void kwsysTerminalSetConsoleColor(HANDLE hOut,
|
||||
case kwsysTerminal_Color_BackgroundWhite:
|
||||
attributes |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
|
||||
break;
|
||||
}
|
||||
if(color & kwsysTerminal_Color_ForegroundBold)
|
||||
{
|
||||
}
|
||||
if (color & kwsysTerminal_Color_ForegroundBold) {
|
||||
attributes |= FOREGROUND_INTENSITY;
|
||||
}
|
||||
if(color & kwsysTerminal_Color_BackgroundBold)
|
||||
{
|
||||
}
|
||||
if (color & kwsysTerminal_Color_BackgroundBold) {
|
||||
attributes |= BACKGROUND_INTENSITY;
|
||||
}
|
||||
}
|
||||
fflush(stream);
|
||||
SetConsoleTextAttribute(hOut, attributes);
|
||||
}
|
||||
|
||||
+101
-90
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_Terminal_h
|
||||
#define @KWSYS_NAMESPACE@_Terminal_h
|
||||
|
||||
@@ -21,41 +12,61 @@
|
||||
not visible to user code. Use kwsysHeaderDump.pl to reproduce
|
||||
these macros after making changes to the interface. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
|
||||
#define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
|
||||
#endif
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# define kwsysTerminal_cfprintf kwsys_ns(Terminal_cfprintf)
|
||||
# define kwsysTerminal_Color_e kwsys_ns(Terminal_Color_e)
|
||||
# define kwsysTerminal_Color_Normal kwsys_ns(Terminal_Color_Normal)
|
||||
# define kwsysTerminal_Color_ForegroundBlack kwsys_ns(Terminal_Color_ForegroundBlack)
|
||||
# define kwsysTerminal_Color_ForegroundRed kwsys_ns(Terminal_Color_ForegroundRed)
|
||||
# define kwsysTerminal_Color_ForegroundGreen kwsys_ns(Terminal_Color_ForegroundGreen)
|
||||
# define kwsysTerminal_Color_ForegroundYellow kwsys_ns(Terminal_Color_ForegroundYellow)
|
||||
# define kwsysTerminal_Color_ForegroundBlue kwsys_ns(Terminal_Color_ForegroundBlue)
|
||||
# define kwsysTerminal_Color_ForegroundMagenta kwsys_ns(Terminal_Color_ForegroundMagenta)
|
||||
# define kwsysTerminal_Color_ForegroundCyan kwsys_ns(Terminal_Color_ForegroundCyan)
|
||||
# define kwsysTerminal_Color_ForegroundWhite kwsys_ns(Terminal_Color_ForegroundWhite)
|
||||
# define kwsysTerminal_Color_ForegroundMask kwsys_ns(Terminal_Color_ForegroundMask)
|
||||
# define kwsysTerminal_Color_BackgroundBlack kwsys_ns(Terminal_Color_BackgroundBlack)
|
||||
# define kwsysTerminal_Color_BackgroundRed kwsys_ns(Terminal_Color_BackgroundRed)
|
||||
# define kwsysTerminal_Color_BackgroundGreen kwsys_ns(Terminal_Color_BackgroundGreen)
|
||||
# define kwsysTerminal_Color_BackgroundYellow kwsys_ns(Terminal_Color_BackgroundYellow)
|
||||
# define kwsysTerminal_Color_BackgroundBlue kwsys_ns(Terminal_Color_BackgroundBlue)
|
||||
# define kwsysTerminal_Color_BackgroundMagenta kwsys_ns(Terminal_Color_BackgroundMagenta)
|
||||
# define kwsysTerminal_Color_BackgroundCyan kwsys_ns(Terminal_Color_BackgroundCyan)
|
||||
# define kwsysTerminal_Color_BackgroundWhite kwsys_ns(Terminal_Color_BackgroundWhite)
|
||||
# define kwsysTerminal_Color_BackgroundMask kwsys_ns(Terminal_Color_BackgroundMask)
|
||||
# define kwsysTerminal_Color_ForegroundBold kwsys_ns(Terminal_Color_ForegroundBold)
|
||||
# define kwsysTerminal_Color_BackgroundBold kwsys_ns(Terminal_Color_BackgroundBold)
|
||||
# define kwsysTerminal_Color_AssumeTTY kwsys_ns(Terminal_Color_AssumeTTY)
|
||||
# define kwsysTerminal_Color_AssumeVT100 kwsys_ns(Terminal_Color_AssumeVT100)
|
||||
# define kwsysTerminal_Color_AttributeMask kwsys_ns(Terminal_Color_AttributeMask)
|
||||
#define kwsysTerminal_cfprintf kwsys_ns(Terminal_cfprintf)
|
||||
#define kwsysTerminal_Color_e kwsys_ns(Terminal_Color_e)
|
||||
#define kwsysTerminal_Color_Normal kwsys_ns(Terminal_Color_Normal)
|
||||
#define kwsysTerminal_Color_ForegroundBlack \
|
||||
kwsys_ns(Terminal_Color_ForegroundBlack)
|
||||
#define kwsysTerminal_Color_ForegroundRed \
|
||||
kwsys_ns(Terminal_Color_ForegroundRed)
|
||||
#define kwsysTerminal_Color_ForegroundGreen \
|
||||
kwsys_ns(Terminal_Color_ForegroundGreen)
|
||||
#define kwsysTerminal_Color_ForegroundYellow \
|
||||
kwsys_ns(Terminal_Color_ForegroundYellow)
|
||||
#define kwsysTerminal_Color_ForegroundBlue \
|
||||
kwsys_ns(Terminal_Color_ForegroundBlue)
|
||||
#define kwsysTerminal_Color_ForegroundMagenta \
|
||||
kwsys_ns(Terminal_Color_ForegroundMagenta)
|
||||
#define kwsysTerminal_Color_ForegroundCyan \
|
||||
kwsys_ns(Terminal_Color_ForegroundCyan)
|
||||
#define kwsysTerminal_Color_ForegroundWhite \
|
||||
kwsys_ns(Terminal_Color_ForegroundWhite)
|
||||
#define kwsysTerminal_Color_ForegroundMask \
|
||||
kwsys_ns(Terminal_Color_ForegroundMask)
|
||||
#define kwsysTerminal_Color_BackgroundBlack \
|
||||
kwsys_ns(Terminal_Color_BackgroundBlack)
|
||||
#define kwsysTerminal_Color_BackgroundRed \
|
||||
kwsys_ns(Terminal_Color_BackgroundRed)
|
||||
#define kwsysTerminal_Color_BackgroundGreen \
|
||||
kwsys_ns(Terminal_Color_BackgroundGreen)
|
||||
#define kwsysTerminal_Color_BackgroundYellow \
|
||||
kwsys_ns(Terminal_Color_BackgroundYellow)
|
||||
#define kwsysTerminal_Color_BackgroundBlue \
|
||||
kwsys_ns(Terminal_Color_BackgroundBlue)
|
||||
#define kwsysTerminal_Color_BackgroundMagenta \
|
||||
kwsys_ns(Terminal_Color_BackgroundMagenta)
|
||||
#define kwsysTerminal_Color_BackgroundCyan \
|
||||
kwsys_ns(Terminal_Color_BackgroundCyan)
|
||||
#define kwsysTerminal_Color_BackgroundWhite \
|
||||
kwsys_ns(Terminal_Color_BackgroundWhite)
|
||||
#define kwsysTerminal_Color_BackgroundMask \
|
||||
kwsys_ns(Terminal_Color_BackgroundMask)
|
||||
#define kwsysTerminal_Color_ForegroundBold \
|
||||
kwsys_ns(Terminal_Color_ForegroundBold)
|
||||
#define kwsysTerminal_Color_BackgroundBold \
|
||||
kwsys_ns(Terminal_Color_BackgroundBold)
|
||||
#define kwsysTerminal_Color_AssumeTTY kwsys_ns(Terminal_Color_AssumeTTY)
|
||||
#define kwsysTerminal_Color_AssumeVT100 kwsys_ns(Terminal_Color_AssumeVT100)
|
||||
#define kwsysTerminal_Color_AttributeMask \
|
||||
kwsys_ns(Terminal_Color_AttributeMask)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -88,33 +99,33 @@ enum kwsysTerminal_Color_e
|
||||
kwsysTerminal_Color_Normal = 0,
|
||||
|
||||
/* Foreground Color */
|
||||
kwsysTerminal_Color_ForegroundBlack = 0x1,
|
||||
kwsysTerminal_Color_ForegroundRed = 0x2,
|
||||
kwsysTerminal_Color_ForegroundGreen = 0x3,
|
||||
kwsysTerminal_Color_ForegroundYellow = 0x4,
|
||||
kwsysTerminal_Color_ForegroundBlue = 0x5,
|
||||
kwsysTerminal_Color_ForegroundBlack = 0x1,
|
||||
kwsysTerminal_Color_ForegroundRed = 0x2,
|
||||
kwsysTerminal_Color_ForegroundGreen = 0x3,
|
||||
kwsysTerminal_Color_ForegroundYellow = 0x4,
|
||||
kwsysTerminal_Color_ForegroundBlue = 0x5,
|
||||
kwsysTerminal_Color_ForegroundMagenta = 0x6,
|
||||
kwsysTerminal_Color_ForegroundCyan = 0x7,
|
||||
kwsysTerminal_Color_ForegroundWhite = 0x8,
|
||||
kwsysTerminal_Color_ForegroundMask = 0xF,
|
||||
kwsysTerminal_Color_ForegroundCyan = 0x7,
|
||||
kwsysTerminal_Color_ForegroundWhite = 0x8,
|
||||
kwsysTerminal_Color_ForegroundMask = 0xF,
|
||||
|
||||
/* Background Color */
|
||||
kwsysTerminal_Color_BackgroundBlack = 0x10,
|
||||
kwsysTerminal_Color_BackgroundRed = 0x20,
|
||||
kwsysTerminal_Color_BackgroundGreen = 0x30,
|
||||
kwsysTerminal_Color_BackgroundYellow = 0x40,
|
||||
kwsysTerminal_Color_BackgroundBlue = 0x50,
|
||||
kwsysTerminal_Color_BackgroundBlack = 0x10,
|
||||
kwsysTerminal_Color_BackgroundRed = 0x20,
|
||||
kwsysTerminal_Color_BackgroundGreen = 0x30,
|
||||
kwsysTerminal_Color_BackgroundYellow = 0x40,
|
||||
kwsysTerminal_Color_BackgroundBlue = 0x50,
|
||||
kwsysTerminal_Color_BackgroundMagenta = 0x60,
|
||||
kwsysTerminal_Color_BackgroundCyan = 0x70,
|
||||
kwsysTerminal_Color_BackgroundWhite = 0x80,
|
||||
kwsysTerminal_Color_BackgroundMask = 0xF0,
|
||||
kwsysTerminal_Color_BackgroundCyan = 0x70,
|
||||
kwsysTerminal_Color_BackgroundWhite = 0x80,
|
||||
kwsysTerminal_Color_BackgroundMask = 0xF0,
|
||||
|
||||
/* Attributes */
|
||||
kwsysTerminal_Color_ForegroundBold = 0x100,
|
||||
kwsysTerminal_Color_BackgroundBold = 0x200,
|
||||
kwsysTerminal_Color_AssumeTTY = 0x400,
|
||||
kwsysTerminal_Color_AssumeVT100 = 0x800,
|
||||
kwsysTerminal_Color_AttributeMask = 0xF00
|
||||
kwsysTerminal_Color_AssumeTTY = 0x400,
|
||||
kwsysTerminal_Color_AssumeVT100 = 0x800,
|
||||
kwsysTerminal_Color_AttributeMask = 0xF00
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -124,36 +135,36 @@ enum kwsysTerminal_Color_e
|
||||
/* If we are building a kwsys .c or .cxx file, let it use these macros.
|
||||
Otherwise, undefine them to keep the namespace clean. */
|
||||
#if !defined(KWSYS_NAMESPACE)
|
||||
# undef kwsys_ns
|
||||
# undef kwsysEXPORT
|
||||
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
# undef kwsysTerminal_cfprintf
|
||||
# undef kwsysTerminal_Color_e
|
||||
# undef kwsysTerminal_Color_Normal
|
||||
# undef kwsysTerminal_Color_ForegroundBlack
|
||||
# undef kwsysTerminal_Color_ForegroundRed
|
||||
# undef kwsysTerminal_Color_ForegroundGreen
|
||||
# undef kwsysTerminal_Color_ForegroundYellow
|
||||
# undef kwsysTerminal_Color_ForegroundBlue
|
||||
# undef kwsysTerminal_Color_ForegroundMagenta
|
||||
# undef kwsysTerminal_Color_ForegroundCyan
|
||||
# undef kwsysTerminal_Color_ForegroundWhite
|
||||
# undef kwsysTerminal_Color_ForegroundMask
|
||||
# undef kwsysTerminal_Color_BackgroundBlack
|
||||
# undef kwsysTerminal_Color_BackgroundRed
|
||||
# undef kwsysTerminal_Color_BackgroundGreen
|
||||
# undef kwsysTerminal_Color_BackgroundYellow
|
||||
# undef kwsysTerminal_Color_BackgroundBlue
|
||||
# undef kwsysTerminal_Color_BackgroundMagenta
|
||||
# undef kwsysTerminal_Color_BackgroundCyan
|
||||
# undef kwsysTerminal_Color_BackgroundWhite
|
||||
# undef kwsysTerminal_Color_BackgroundMask
|
||||
# undef kwsysTerminal_Color_ForegroundBold
|
||||
# undef kwsysTerminal_Color_BackgroundBold
|
||||
# undef kwsysTerminal_Color_AssumeTTY
|
||||
# undef kwsysTerminal_Color_AssumeVT100
|
||||
# undef kwsysTerminal_Color_AttributeMask
|
||||
# endif
|
||||
#undef kwsys_ns
|
||||
#undef kwsysEXPORT
|
||||
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
#undef kwsysTerminal_cfprintf
|
||||
#undef kwsysTerminal_Color_e
|
||||
#undef kwsysTerminal_Color_Normal
|
||||
#undef kwsysTerminal_Color_ForegroundBlack
|
||||
#undef kwsysTerminal_Color_ForegroundRed
|
||||
#undef kwsysTerminal_Color_ForegroundGreen
|
||||
#undef kwsysTerminal_Color_ForegroundYellow
|
||||
#undef kwsysTerminal_Color_ForegroundBlue
|
||||
#undef kwsysTerminal_Color_ForegroundMagenta
|
||||
#undef kwsysTerminal_Color_ForegroundCyan
|
||||
#undef kwsysTerminal_Color_ForegroundWhite
|
||||
#undef kwsysTerminal_Color_ForegroundMask
|
||||
#undef kwsysTerminal_Color_BackgroundBlack
|
||||
#undef kwsysTerminal_Color_BackgroundRed
|
||||
#undef kwsysTerminal_Color_BackgroundGreen
|
||||
#undef kwsysTerminal_Color_BackgroundYellow
|
||||
#undef kwsysTerminal_Color_BackgroundBlue
|
||||
#undef kwsysTerminal_Color_BackgroundMagenta
|
||||
#undef kwsysTerminal_Color_BackgroundCyan
|
||||
#undef kwsysTerminal_Color_BackgroundWhite
|
||||
#undef kwsysTerminal_Color_BackgroundMask
|
||||
#undef kwsysTerminal_Color_ForegroundBold
|
||||
#undef kwsysTerminal_Color_BackgroundBold
|
||||
#undef kwsysTerminal_Color_AssumeTTY
|
||||
#undef kwsysTerminal_Color_AssumeVT100
|
||||
#undef kwsysTerminal_Color_AttributeMask
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
@@ -38,108 +29,134 @@
|
||||
#define @KWSYS_NAMESPACE@_hash_fun_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <string>
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
template <class _Key> struct hash { };
|
||||
template <class _Key>
|
||||
struct hash
|
||||
{
|
||||
};
|
||||
|
||||
inline size_t _stl_hash_string(const char* __s)
|
||||
{
|
||||
unsigned long __h = 0;
|
||||
for ( ; *__s; ++__s)
|
||||
__h = 5*__h + *__s;
|
||||
for (; *__s; ++__s)
|
||||
__h = 5 * __h + *__s;
|
||||
|
||||
return size_t(__h);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct hash<char*> {
|
||||
struct hash<char*>
|
||||
{
|
||||
size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<const char*> {
|
||||
struct hash<const char*>
|
||||
{
|
||||
size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<std::string> {
|
||||
size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
|
||||
struct hash<std::string>
|
||||
{
|
||||
size_t operator()(const std::string& __s) const
|
||||
{
|
||||
return _stl_hash_string(__s.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(__BORLANDC__)
|
||||
template <>
|
||||
struct hash<const std::string> {
|
||||
size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
|
||||
struct hash<const std::string>
|
||||
{
|
||||
size_t operator()(const std::string& __s) const
|
||||
{
|
||||
return _stl_hash_string(__s.c_str());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct hash<char> {
|
||||
struct hash<char>
|
||||
{
|
||||
size_t operator()(char __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<unsigned char> {
|
||||
struct hash<unsigned char>
|
||||
{
|
||||
size_t operator()(unsigned char __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<signed char> {
|
||||
struct hash<signed char>
|
||||
{
|
||||
size_t operator()(unsigned char __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<short> {
|
||||
struct hash<short>
|
||||
{
|
||||
size_t operator()(short __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<unsigned short> {
|
||||
struct hash<unsigned short>
|
||||
{
|
||||
size_t operator()(unsigned short __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<int> {
|
||||
struct hash<int>
|
||||
{
|
||||
size_t operator()(int __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<unsigned int> {
|
||||
struct hash<unsigned int>
|
||||
{
|
||||
size_t operator()(unsigned int __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<long> {
|
||||
struct hash<long>
|
||||
{
|
||||
size_t operator()(long __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<unsigned long> {
|
||||
struct hash<unsigned long>
|
||||
{
|
||||
size_t operator()(unsigned long __x) const { return __x; }
|
||||
};
|
||||
|
||||
// use long long or __int64
|
||||
#if @KWSYS_USE_LONG_LONG@
|
||||
template <>
|
||||
struct hash<long long> {
|
||||
struct hash<long long>
|
||||
{
|
||||
size_t operator()(long long __x) const { return __x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<unsigned long long> {
|
||||
struct hash<unsigned long long>
|
||||
{
|
||||
size_t operator()(unsigned long long __x) const { return __x; }
|
||||
};
|
||||
#elif @KWSYS_USE___INT64@
|
||||
template <>
|
||||
struct hash<__int64> {
|
||||
struct hash<__int64>
|
||||
{
|
||||
size_t operator()(__int64 __x) const { return __x; }
|
||||
};
|
||||
template <>
|
||||
struct hash<unsigned __int64> {
|
||||
struct hash<unsigned __int64>
|
||||
{
|
||||
size_t operator()(unsigned __int64 __x) const { return __x; }
|
||||
};
|
||||
#endif // use long long or __int64
|
||||
|
||||
+147
-99
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
@@ -38,36 +29,37 @@
|
||||
#define @KWSYS_NAMESPACE@_hash_map_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/hashtable.hxx>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
|
||||
|
||||
#include <functional> // equal_to
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4284)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4284)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
|
||||
# pragma set woff 1174
|
||||
# pragma set woff 1375
|
||||
#pragma set woff 1174
|
||||
#pragma set woff 1375
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
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 : public std::unary_function<std::pair<T1, T2>, T1>
|
||||
{
|
||||
const T1& operator()(const std::pair<T1, T2>& __x) const
|
||||
{ return __x.first; }
|
||||
{
|
||||
return __x.first;
|
||||
}
|
||||
};
|
||||
|
||||
// Forward declaration of equality operator; needed for friend declaration.
|
||||
|
||||
template <class _Key, class _Tp,
|
||||
class _HashFcn = hash<_Key>,
|
||||
template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
|
||||
class _EqualKey = std::equal_to<_Key>,
|
||||
class _Alloc = std::allocator<char> >
|
||||
class hash_map;
|
||||
@@ -76,13 +68,13 @@ template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
|
||||
bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&,
|
||||
const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&);
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
|
||||
class _Alloc>
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
class hash_map
|
||||
{
|
||||
private:
|
||||
typedef hashtable<std::pair<const _Key,_Tp>,_Key,_HashFcn,
|
||||
hash_select1st<const _Key,_Tp>,_EqualKey,_Alloc> _Ht;
|
||||
typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
|
||||
hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
|
||||
_Ht;
|
||||
_Ht _M_ht;
|
||||
|
||||
public:
|
||||
@@ -110,34 +102,51 @@ public:
|
||||
allocator_type get_allocator() const { return _M_ht.get_allocator(); }
|
||||
|
||||
public:
|
||||
hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
|
||||
hash_map()
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
explicit hash_map(size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_map(size_type __n, const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a) {}
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
hash_map(_InputIterator __f, _InputIterator __l)
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
|
||||
public:
|
||||
size_type size() const { return _M_ht.size(); }
|
||||
@@ -145,8 +154,7 @@ public:
|
||||
bool empty() const { return _M_ht.empty(); }
|
||||
void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
|
||||
|
||||
friend bool operator==<>(const hash_map&,
|
||||
const hash_map&);
|
||||
friend bool operator==<>(const hash_map&, const hash_map&);
|
||||
|
||||
iterator begin() { return _M_ht.begin(); }
|
||||
iterator end() { return _M_ht.end(); }
|
||||
@@ -154,31 +162,44 @@ public:
|
||||
const_iterator end() const { return _M_ht.end(); }
|
||||
|
||||
public:
|
||||
std::pair<iterator,bool> insert(const value_type& __obj)
|
||||
{ return _M_ht.insert_unique(__obj); }
|
||||
std::pair<iterator, bool> insert(const value_type& __obj)
|
||||
{
|
||||
return _M_ht.insert_unique(__obj);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
void insert(_InputIterator __f, _InputIterator __l)
|
||||
{ _M_ht.insert_unique(__f,__l); }
|
||||
std::pair<iterator,bool> insert_noresize(const value_type& __obj)
|
||||
{ return _M_ht.insert_unique_noresize(__obj); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
std::pair<iterator, bool> insert_noresize(const value_type& __obj)
|
||||
{
|
||||
return _M_ht.insert_unique_noresize(__obj);
|
||||
}
|
||||
|
||||
iterator find(const key_type& __key) { return _M_ht.find(__key); }
|
||||
const_iterator find(const key_type& __key) const
|
||||
{ return _M_ht.find(__key); }
|
||||
{
|
||||
return _M_ht.find(__key);
|
||||
}
|
||||
|
||||
_Tp& operator[](const key_type& __key) {
|
||||
_Tp& operator[](const key_type& __key)
|
||||
{
|
||||
return _M_ht.find_or_insert(value_type(__key, _Tp())).second;
|
||||
}
|
||||
|
||||
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& __key)
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
const key_type& __key) const
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
|
||||
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
|
||||
size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
|
||||
void erase(iterator __it) { _M_ht.erase(__it); }
|
||||
void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
|
||||
void clear() { _M_ht.clear(); }
|
||||
@@ -187,53 +208,51 @@ public:
|
||||
size_type bucket_count() const { return _M_ht.bucket_count(); }
|
||||
size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
|
||||
size_type elems_in_bucket(size_type __n) const
|
||||
{ return _M_ht.elems_in_bucket(__n); }
|
||||
{
|
||||
return _M_ht.elems_in_bucket(__n);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
|
||||
const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
|
||||
bool operator==(const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
|
||||
const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
|
||||
{
|
||||
return __hm1._M_ht == __hm2._M_ht;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
|
||||
inline bool
|
||||
operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
|
||||
const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) {
|
||||
inline bool operator!=(
|
||||
const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
|
||||
const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
|
||||
{
|
||||
return !(__hm1 == __hm2);
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
|
||||
inline void
|
||||
swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
|
||||
hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
|
||||
inline void swap(hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
|
||||
hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
|
||||
{
|
||||
__hm1.swap(__hm2);
|
||||
}
|
||||
|
||||
// Forward declaration of equality operator; needed for friend declaration.
|
||||
|
||||
template <class _Key, class _Tp,
|
||||
class _HashFcn = hash<_Key>,
|
||||
template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
|
||||
class _EqualKey = std::equal_to<_Key>,
|
||||
class _Alloc = std::allocator<char> >
|
||||
class hash_multimap;
|
||||
|
||||
template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
|
||||
const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2);
|
||||
bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
|
||||
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2);
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
|
||||
class _Alloc>
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
class hash_multimap
|
||||
{
|
||||
private:
|
||||
typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
|
||||
hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
|
||||
_Ht;
|
||||
_Ht;
|
||||
_Ht _M_ht;
|
||||
|
||||
public:
|
||||
@@ -261,34 +280,51 @@ public:
|
||||
allocator_type get_allocator() const { return _M_ht.get_allocator(); }
|
||||
|
||||
public:
|
||||
hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
|
||||
hash_multimap()
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
explicit hash_multimap(size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_multimap(size_type __n, const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a) {}
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
hash_multimap(_InputIterator __f, _InputIterator __l)
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
|
||||
public:
|
||||
size_type size() const { return _M_ht.size(); }
|
||||
@@ -296,8 +332,7 @@ public:
|
||||
bool empty() const { return _M_ht.empty(); }
|
||||
void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
|
||||
|
||||
friend bool operator==<>(const hash_multimap&,
|
||||
const hash_multimap&);
|
||||
friend bool operator==<>(const hash_multimap&, const hash_multimap&);
|
||||
|
||||
iterator begin() { return _M_ht.begin(); }
|
||||
iterator end() { return _M_ht.end(); }
|
||||
@@ -306,26 +341,38 @@ public:
|
||||
|
||||
public:
|
||||
iterator insert(const value_type& __obj)
|
||||
{ return _M_ht.insert_equal(__obj); }
|
||||
{
|
||||
return _M_ht.insert_equal(__obj);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
void insert(_InputIterator __f, _InputIterator __l)
|
||||
{ _M_ht.insert_equal(__f,__l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
iterator insert_noresize(const value_type& __obj)
|
||||
{ return _M_ht.insert_equal_noresize(__obj); }
|
||||
{
|
||||
return _M_ht.insert_equal_noresize(__obj);
|
||||
}
|
||||
|
||||
iterator find(const key_type& __key) { return _M_ht.find(__key); }
|
||||
const_iterator find(const key_type& __key) const
|
||||
{ return _M_ht.find(__key); }
|
||||
{
|
||||
return _M_ht.find(__key);
|
||||
}
|
||||
|
||||
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& __key)
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
const key_type& __key) const
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
|
||||
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
|
||||
size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
|
||||
void erase(iterator __it) { _M_ht.erase(__it); }
|
||||
void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
|
||||
void clear() { _M_ht.clear(); }
|
||||
@@ -335,28 +382,29 @@ public:
|
||||
size_type bucket_count() const { return _M_ht.bucket_count(); }
|
||||
size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
|
||||
size_type elems_in_bucket(size_type __n) const
|
||||
{ return _M_ht.elems_in_bucket(__n); }
|
||||
{
|
||||
return _M_ht.elems_in_bucket(__n);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
|
||||
const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2)
|
||||
bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
|
||||
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
|
||||
{
|
||||
return __hm1._M_ht == __hm2._M_ht;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
|
||||
inline bool
|
||||
operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
|
||||
const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) {
|
||||
inline bool operator!=(
|
||||
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
|
||||
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
|
||||
{
|
||||
return !(__hm1 == __hm2);
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
|
||||
inline void
|
||||
swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
|
||||
hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
|
||||
inline void swap(hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
|
||||
hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
|
||||
{
|
||||
__hm1.swap(__hm2);
|
||||
}
|
||||
@@ -364,12 +412,12 @@ swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
|
||||
# pragma reset woff 1174
|
||||
# pragma reset woff 1375
|
||||
#pragma reset woff 1174
|
||||
#pragma reset woff 1375
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+125
-92
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
@@ -38,49 +29,49 @@
|
||||
#define @KWSYS_NAMESPACE@_hash_set_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/hashtable.hxx>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
|
||||
|
||||
#include <functional> // equal_to
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4284)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4284)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
|
||||
# pragma set woff 1174
|
||||
# pragma set woff 1375
|
||||
#pragma set woff 1174
|
||||
#pragma set woff 1375
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
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 : public std::unary_function<_Tp, _Tp>
|
||||
{
|
||||
const _Tp& operator()(const _Tp& __x) const { return __x; }
|
||||
};
|
||||
|
||||
// Forward declaration of equality operator; needed for friend declaration.
|
||||
|
||||
template <class _Value,
|
||||
class _HashFcn = hash<_Value>,
|
||||
template <class _Value, class _HashFcn = hash<_Value>,
|
||||
class _EqualKey = std::equal_to<_Value>,
|
||||
class _Alloc = std::allocator<char> >
|
||||
class hash_set;
|
||||
|
||||
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2);
|
||||
bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2);
|
||||
|
||||
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
class hash_set
|
||||
{
|
||||
private:
|
||||
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
|
||||
_EqualKey, _Alloc> _Ht;
|
||||
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
|
||||
_Alloc>
|
||||
_Ht;
|
||||
_Ht _M_ht;
|
||||
|
||||
public:
|
||||
@@ -107,34 +98,50 @@ public:
|
||||
|
||||
public:
|
||||
hash_set()
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
explicit hash_set(size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_set(size_type __n, const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a) {}
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
hash_set(_InputIterator __f, _InputIterator __l)
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{ _M_ht.insert_unique(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
|
||||
public:
|
||||
size_type size() const { return _M_ht.size(); }
|
||||
@@ -142,27 +149,27 @@ public:
|
||||
bool empty() const { return _M_ht.empty(); }
|
||||
void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); }
|
||||
|
||||
friend bool operator==<>(const hash_set&,
|
||||
const hash_set&);
|
||||
friend bool operator==<>(const hash_set&, const hash_set&);
|
||||
|
||||
iterator begin() const { return _M_ht.begin(); }
|
||||
iterator end() const { return _M_ht.end(); }
|
||||
|
||||
public:
|
||||
std::pair<iterator, bool> insert(const value_type& __obj)
|
||||
{
|
||||
typedef typename _Ht::iterator _Ht_iterator;
|
||||
std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
|
||||
return std::pair<iterator,bool>(__p.first, __p.second);
|
||||
}
|
||||
{
|
||||
typedef typename _Ht::iterator _Ht_iterator;
|
||||
std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
|
||||
return std::pair<iterator, bool>(__p.first, __p.second);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
void insert(_InputIterator __f, _InputIterator __l)
|
||||
{ _M_ht.insert_unique(__f,__l); }
|
||||
{
|
||||
_M_ht.insert_unique(__f, __l);
|
||||
}
|
||||
std::pair<iterator, bool> insert_noresize(const value_type& __obj)
|
||||
{
|
||||
typedef typename _Ht::iterator _Ht_iterator;
|
||||
std::pair<_Ht_iterator, bool> __p =
|
||||
_M_ht.insert_unique_noresize(__obj);
|
||||
std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique_noresize(__obj);
|
||||
return std::pair<iterator, bool>(__p.first, __p.second);
|
||||
}
|
||||
|
||||
@@ -171,9 +178,11 @@ public:
|
||||
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& __key) const
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
|
||||
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
|
||||
size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
|
||||
void erase(iterator __it) { _M_ht.erase(__it); }
|
||||
void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
|
||||
void clear() { _M_ht.clear(); }
|
||||
@@ -183,50 +192,49 @@ public:
|
||||
size_type bucket_count() const { return _M_ht.bucket_count(); }
|
||||
size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
|
||||
size_type elems_in_bucket(size_type __n) const
|
||||
{ return _M_ht.elems_in_bucket(__n); }
|
||||
{
|
||||
return _M_ht.elems_in_bucket(__n);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2)
|
||||
bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
return __hs1._M_ht == __hs2._M_ht;
|
||||
}
|
||||
|
||||
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
inline bool
|
||||
operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) {
|
||||
inline bool operator!=(
|
||||
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
return !(__hs1 == __hs2);
|
||||
}
|
||||
|
||||
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
inline void
|
||||
swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2)
|
||||
inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
__hs1.swap(__hs2);
|
||||
}
|
||||
|
||||
template <class _Value,
|
||||
class _HashFcn = hash<_Value>,
|
||||
template <class _Value, class _HashFcn = hash<_Value>,
|
||||
class _EqualKey = std::equal_to<_Value>,
|
||||
class _Alloc = std::allocator<char> >
|
||||
class hash_multiset;
|
||||
|
||||
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2);
|
||||
|
||||
bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2);
|
||||
|
||||
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
class hash_multiset
|
||||
{
|
||||
private:
|
||||
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
|
||||
_EqualKey, _Alloc> _Ht;
|
||||
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
|
||||
_Alloc>
|
||||
_Ht;
|
||||
_Ht _M_ht;
|
||||
|
||||
public:
|
||||
@@ -253,34 +261,50 @@ public:
|
||||
|
||||
public:
|
||||
hash_multiset()
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
explicit hash_multiset(size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_multiset(size_type __n, const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a) {}
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
hash_multiset(_InputIterator __f, _InputIterator __l)
|
||||
: _M_ht(100, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
|
||||
: _M_ht(__n, hasher(), key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf)
|
||||
: _M_ht(__n, __hf, key_equal(), allocator_type())
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
|
||||
const hasher& __hf, const key_equal& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_ht(__n, __hf, __eql, __a)
|
||||
{ _M_ht.insert_equal(__f, __l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
|
||||
public:
|
||||
size_type size() const { return _M_ht.size(); }
|
||||
@@ -288,29 +312,36 @@ public:
|
||||
bool empty() const { return _M_ht.empty(); }
|
||||
void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); }
|
||||
|
||||
friend bool operator==<>(const hash_multiset&,
|
||||
const hash_multiset&);
|
||||
friend bool operator==<>(const hash_multiset&, const hash_multiset&);
|
||||
|
||||
iterator begin() const { return _M_ht.begin(); }
|
||||
iterator end() const { return _M_ht.end(); }
|
||||
|
||||
public:
|
||||
iterator insert(const value_type& __obj)
|
||||
{ return _M_ht.insert_equal(__obj); }
|
||||
{
|
||||
return _M_ht.insert_equal(__obj);
|
||||
}
|
||||
template <class _InputIterator>
|
||||
void insert(_InputIterator __f, _InputIterator __l)
|
||||
{ _M_ht.insert_equal(__f,__l); }
|
||||
{
|
||||
_M_ht.insert_equal(__f, __l);
|
||||
}
|
||||
iterator insert_noresize(const value_type& __obj)
|
||||
{ return _M_ht.insert_equal_noresize(__obj); }
|
||||
{
|
||||
return _M_ht.insert_equal_noresize(__obj);
|
||||
}
|
||||
|
||||
iterator find(const key_type& __key) const { return _M_ht.find(__key); }
|
||||
|
||||
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& __key) const
|
||||
{ return _M_ht.equal_range(__key); }
|
||||
{
|
||||
return _M_ht.equal_range(__key);
|
||||
}
|
||||
|
||||
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
|
||||
size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
|
||||
void erase(iterator __it) { _M_ht.erase(__it); }
|
||||
void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
|
||||
void clear() { _M_ht.clear(); }
|
||||
@@ -320,40 +351,42 @@ public:
|
||||
size_type bucket_count() const { return _M_ht.bucket_count(); }
|
||||
size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
|
||||
size_type elems_in_bucket(size_type __n) const
|
||||
{ return _M_ht.elems_in_bucket(__n); }
|
||||
{
|
||||
return _M_ht.elems_in_bucket(__n);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
bool
|
||||
operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2)
|
||||
bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
return __hs1._M_ht == __hs2._M_ht;
|
||||
}
|
||||
|
||||
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
inline bool
|
||||
operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) {
|
||||
inline bool operator!=(
|
||||
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
return !(__hs1 == __hs2);
|
||||
}
|
||||
|
||||
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
|
||||
inline void
|
||||
swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
|
||||
hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) {
|
||||
inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
|
||||
hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
|
||||
{
|
||||
__hs1.swap(__hs2);
|
||||
}
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
|
||||
# pragma reset woff 1174
|
||||
# pragma reset woff 1375
|
||||
#pragma reset woff 1174
|
||||
#pragma reset woff 1375
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+240
-244
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
@@ -35,31 +26,31 @@
|
||||
*
|
||||
*/
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8027 /* 'for' not inlined. */
|
||||
# pragma warn -8026 /* 'exception' not inlined. */
|
||||
#endif
|
||||
#pragma warn - 8027 /* 'for' not inlined. */
|
||||
#pragma warn - 8026 /* 'exception' not inlined. */
|
||||
#endif
|
||||
|
||||
#ifndef @KWSYS_NAMESPACE@_hashtable_hxx
|
||||
#define @KWSYS_NAMESPACE@_hashtable_hxx
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#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
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4284)
|
||||
# pragma warning (disable:4786)
|
||||
# pragma warning (disable:4512) /* no assignment operator for class */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4284)
|
||||
#pragma warning(disable : 4786)
|
||||
#pragma warning(disable : 4512) /* no assignment operator for class */
|
||||
#endif
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 3970 /* pointer to int conversion */ 3321 3968
|
||||
#pragma set woff 3970 /* pointer to int conversion */ 3321 3968
|
||||
#endif
|
||||
|
||||
// In C++11, clang will warn about using dynamic exception specifications
|
||||
@@ -67,14 +58,13 @@
|
||||
// mimic unordered_set and unordered_map, we want to keep the 'throw()'
|
||||
// decorations below. So we suppress the warning.
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wdeprecated")
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated"
|
||||
# endif
|
||||
#if __has_warning("-Wdeprecated")
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace @KWSYS_NAMESPACE@
|
||||
{
|
||||
namespace @KWSYS_NAMESPACE@ {
|
||||
|
||||
template <class _Val>
|
||||
struct _Hashtable_node
|
||||
@@ -82,34 +72,35 @@ struct _Hashtable_node
|
||||
_Hashtable_node* _M_next;
|
||||
_Val _M_val;
|
||||
void public_method_to_quiet_warning_about_all_methods_private();
|
||||
|
||||
private:
|
||||
void operator=(_Hashtable_node<_Val> const&); // poison node assignment
|
||||
};
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey,
|
||||
class _Alloc = std::allocator<char> >
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc = std::allocator<char> >
|
||||
class hashtable;
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey, class _Alloc>
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_iterator;
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey, class _Alloc>
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_const_iterator;
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_iterator {
|
||||
typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
|
||||
_Hashtable;
|
||||
typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
|
||||
_ExtractKey, _EqualKey, _Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
|
||||
_ExtractKey, _EqualKey, _Alloc>
|
||||
const_iterator;
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_iterator
|
||||
{
|
||||
typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
|
||||
_Hashtable;
|
||||
typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
|
||||
_Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
|
||||
_EqualKey, _Alloc>
|
||||
const_iterator;
|
||||
typedef _Hashtable_node<_Val> _Node;
|
||||
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
@@ -123,30 +114,31 @@ struct _Hashtable_iterator {
|
||||
_Hashtable* _M_ht;
|
||||
|
||||
_Hashtable_iterator(_Node* __n, _Hashtable* __tab)
|
||||
: _M_cur(__n), _M_ht(__tab) {}
|
||||
: _M_cur(__n)
|
||||
, _M_ht(__tab)
|
||||
{
|
||||
}
|
||||
_Hashtable_iterator() {}
|
||||
reference operator*() const { return _M_cur->_M_val; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
iterator& operator++();
|
||||
iterator operator++(int);
|
||||
bool operator==(const iterator& __it) const
|
||||
{ return _M_cur == __it._M_cur; }
|
||||
bool operator!=(const iterator& __it) const
|
||||
{ return _M_cur != __it._M_cur; }
|
||||
bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; }
|
||||
bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; }
|
||||
};
|
||||
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_const_iterator {
|
||||
typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
|
||||
_Hashtable;
|
||||
typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
|
||||
_ExtractKey,_EqualKey,_Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
|
||||
_ExtractKey, _EqualKey, _Alloc>
|
||||
const_iterator;
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc>
|
||||
struct _Hashtable_const_iterator
|
||||
{
|
||||
typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
|
||||
_Hashtable;
|
||||
typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
|
||||
_Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
|
||||
_EqualKey, _Alloc>
|
||||
const_iterator;
|
||||
typedef _Hashtable_node<_Val> _Node;
|
||||
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
@@ -160,39 +152,53 @@ struct _Hashtable_const_iterator {
|
||||
const _Hashtable* _M_ht;
|
||||
|
||||
_Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
|
||||
: _M_cur(__n), _M_ht(__tab) {}
|
||||
: _M_cur(__n)
|
||||
, _M_ht(__tab)
|
||||
{
|
||||
}
|
||||
_Hashtable_const_iterator() {}
|
||||
_Hashtable_const_iterator(const iterator& __it)
|
||||
: _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
|
||||
: _M_cur(__it._M_cur)
|
||||
, _M_ht(__it._M_ht)
|
||||
{
|
||||
}
|
||||
reference operator*() const { return _M_cur->_M_val; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
const_iterator& operator++();
|
||||
const_iterator operator++(int);
|
||||
bool operator==(const const_iterator& __it) const
|
||||
{ return _M_cur == __it._M_cur; }
|
||||
{
|
||||
return _M_cur == __it._M_cur;
|
||||
}
|
||||
bool operator!=(const const_iterator& __it) const
|
||||
{ return _M_cur != __it._M_cur; }
|
||||
{
|
||||
return _M_cur != __it._M_cur;
|
||||
}
|
||||
};
|
||||
|
||||
// Note: assumes long is at least 32 bits.
|
||||
enum { _stl_num_primes = 31 };
|
||||
enum
|
||||
{
|
||||
_stl_num_primes = 31
|
||||
};
|
||||
|
||||
// create a function with a static local to that function that returns
|
||||
// the static
|
||||
static inline const unsigned long* get_stl_prime_list() {
|
||||
|
||||
static const unsigned long _stl_prime_list[_stl_num_primes] =
|
||||
static inline const unsigned long* get_stl_prime_list()
|
||||
{
|
||||
5ul, 11ul, 23ul,
|
||||
53ul, 97ul, 193ul, 389ul, 769ul,
|
||||
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
|
||||
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
|
||||
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
|
||||
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
|
||||
1610612741ul, 3221225473ul, 4294967291ul
|
||||
};
|
||||
|
||||
return &_stl_prime_list[0]; }
|
||||
static const unsigned long _stl_prime_list[_stl_num_primes] = {
|
||||
5ul, 11ul, 23ul, 53ul, 97ul,
|
||||
193ul, 389ul, 769ul, 1543ul, 3079ul,
|
||||
6151ul, 12289ul, 24593ul, 49157ul, 98317ul,
|
||||
196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul,
|
||||
6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul,
|
||||
201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul,
|
||||
4294967291ul
|
||||
};
|
||||
|
||||
return &_stl_prime_list[0];
|
||||
}
|
||||
|
||||
static inline size_t _stl_next_prime(size_t __n)
|
||||
{
|
||||
@@ -208,8 +214,8 @@ template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
class hashtable;
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
|
||||
const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
|
||||
bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
|
||||
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
|
||||
|
||||
// Hashtables handle allocators a bit differently than other containers
|
||||
// do. If we're using standard-conforming allocators, then a hashtable
|
||||
@@ -219,20 +225,21 @@ bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
|
||||
// Additionally, a base class wouldn't serve any other purposes; it
|
||||
// wouldn't, for example, simplify the exception-handling code.
|
||||
|
||||
template <class _Val, class _Key, class _HashFcn,
|
||||
class _ExtractKey, class _EqualKey, class _Alloc>
|
||||
class hashtable {
|
||||
template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
|
||||
class _EqualKey, class _Alloc>
|
||||
class hashtable
|
||||
{
|
||||
public:
|
||||
typedef _Key key_type;
|
||||
typedef _Val value_type;
|
||||
typedef _HashFcn hasher;
|
||||
typedef _EqualKey key_equal;
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
|
||||
hasher hash_funct() const { return _M_hash; }
|
||||
@@ -245,75 +252,74 @@ public:
|
||||
typedef typename _Alloc::template rebind<_Val>::other allocator_type;
|
||||
allocator_type get_allocator() const { return _M_node_allocator; }
|
||||
private:
|
||||
typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
|
||||
typedef typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
|
||||
typedef std::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
|
||||
typedef
|
||||
typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
|
||||
typedef
|
||||
typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
|
||||
typedef std::vector<_Node*, _M_node_ptr_allocator_type> _M_buckets_type;
|
||||
|
||||
private:
|
||||
_M_node_allocator_type _M_node_allocator;
|
||||
hasher _M_hash;
|
||||
key_equal _M_equals;
|
||||
_ExtractKey _M_get_key;
|
||||
_M_buckets_type _M_buckets;
|
||||
size_type _M_num_elements;
|
||||
hasher _M_hash;
|
||||
key_equal _M_equals;
|
||||
_ExtractKey _M_get_key;
|
||||
_M_buckets_type _M_buckets;
|
||||
size_type _M_num_elements;
|
||||
|
||||
_Node* _M_get_node() { return _M_node_allocator.allocate(1); }
|
||||
void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
|
||||
|
||||
public:
|
||||
typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
|
||||
_Alloc>
|
||||
const_iterator;
|
||||
typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
|
||||
_Alloc>
|
||||
iterator;
|
||||
typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
|
||||
_EqualKey, _Alloc>
|
||||
const_iterator;
|
||||
|
||||
friend struct
|
||||
_Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
|
||||
friend struct
|
||||
_Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
|
||||
friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
|
||||
_EqualKey, _Alloc>;
|
||||
friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
|
||||
_EqualKey, _Alloc>;
|
||||
|
||||
public:
|
||||
hashtable(size_type __n,
|
||||
const _HashFcn& __hf,
|
||||
const _EqualKey& __eql,
|
||||
hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
|
||||
const _ExtractKey& __ext,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_node_allocator(__a),
|
||||
_M_hash(__hf),
|
||||
_M_equals(__eql),
|
||||
_M_get_key(__ext),
|
||||
_M_buckets(__a),
|
||||
_M_num_elements(0)
|
||||
: _M_node_allocator(__a)
|
||||
, _M_hash(__hf)
|
||||
, _M_equals(__eql)
|
||||
, _M_get_key(__ext)
|
||||
, _M_buckets(__a)
|
||||
, _M_num_elements(0)
|
||||
{
|
||||
_M_initialize_buckets(__n);
|
||||
}
|
||||
|
||||
hashtable(size_type __n,
|
||||
const _HashFcn& __hf,
|
||||
const _EqualKey& __eql,
|
||||
hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
|
||||
const allocator_type& __a = allocator_type())
|
||||
: _M_node_allocator(__a),
|
||||
_M_hash(__hf),
|
||||
_M_equals(__eql),
|
||||
_M_get_key(_ExtractKey()),
|
||||
_M_buckets(__a),
|
||||
_M_num_elements(0)
|
||||
: _M_node_allocator(__a)
|
||||
, _M_hash(__hf)
|
||||
, _M_equals(__eql)
|
||||
, _M_get_key(_ExtractKey())
|
||||
, _M_buckets(__a)
|
||||
, _M_num_elements(0)
|
||||
{
|
||||
_M_initialize_buckets(__n);
|
||||
}
|
||||
|
||||
hashtable(const hashtable& __ht)
|
||||
: _M_node_allocator(__ht.get_allocator()),
|
||||
_M_hash(__ht._M_hash),
|
||||
_M_equals(__ht._M_equals),
|
||||
_M_get_key(__ht._M_get_key),
|
||||
_M_buckets(__ht.get_allocator()),
|
||||
_M_num_elements(0)
|
||||
: _M_node_allocator(__ht.get_allocator())
|
||||
, _M_hash(__ht._M_hash)
|
||||
, _M_equals(__ht._M_equals)
|
||||
, _M_get_key(__ht._M_get_key)
|
||||
, _M_buckets(__ht.get_allocator())
|
||||
, _M_num_elements(0)
|
||||
{
|
||||
_M_copy_from(__ht);
|
||||
}
|
||||
|
||||
hashtable& operator= (const hashtable& __ht)
|
||||
hashtable& operator=(const hashtable& __ht)
|
||||
{
|
||||
if (&__ht != this) {
|
||||
clear();
|
||||
@@ -360,15 +366,15 @@ public:
|
||||
|
||||
const_iterator end() const { return const_iterator(0, this); }
|
||||
|
||||
friend bool operator==<>(const hashtable&,
|
||||
const hashtable&);
|
||||
friend bool operator==<>(const hashtable&, const hashtable&);
|
||||
|
||||
public:
|
||||
|
||||
size_type bucket_count() const { return _M_buckets.size(); }
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{ return get_stl_prime_list()[(int)_stl_num_primes - 1]; }
|
||||
{
|
||||
return get_stl_prime_list()[(int)_stl_num_primes - 1];
|
||||
}
|
||||
|
||||
size_type elems_in_bucket(size_type __bucket) const
|
||||
{
|
||||
@@ -396,14 +402,16 @@ public:
|
||||
template <class _InputIterator>
|
||||
void insert_unique(_InputIterator __f, _InputIterator __l)
|
||||
{
|
||||
insert_unique(__f, __l,
|
||||
insert_unique(
|
||||
__f, __l,
|
||||
typename std::iterator_traits<_InputIterator>::iterator_category());
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
void insert_equal(_InputIterator __f, _InputIterator __l)
|
||||
{
|
||||
insert_equal(__f, __l,
|
||||
insert_equal(
|
||||
__f, __l,
|
||||
typename std::iterator_traits<_InputIterator>::iterator_category());
|
||||
}
|
||||
|
||||
@@ -411,7 +419,7 @@ public:
|
||||
void insert_unique(_InputIterator __f, _InputIterator __l,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
for ( ; __f != __l; ++__f)
|
||||
for (; __f != __l; ++__f)
|
||||
insert_unique(*__f);
|
||||
}
|
||||
|
||||
@@ -419,7 +427,7 @@ public:
|
||||
void insert_equal(_InputIterator __f, _InputIterator __l,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
for ( ; __f != __l; ++__f)
|
||||
for (; __f != __l; ++__f)
|
||||
insert_equal(*__f);
|
||||
}
|
||||
|
||||
@@ -430,7 +438,7 @@ public:
|
||||
size_type __n = 0;
|
||||
std::distance(__f, __l, __n);
|
||||
resize(_M_num_elements + __n);
|
||||
for ( ; __n > 0; --__n, ++__f)
|
||||
for (; __n > 0; --__n, ++__f)
|
||||
insert_unique_noresize(*__f);
|
||||
}
|
||||
|
||||
@@ -441,7 +449,7 @@ public:
|
||||
size_type __n = 0;
|
||||
std::distance(__f, __l, __n);
|
||||
resize(_M_num_elements + __n);
|
||||
for ( ; __n > 0; --__n, ++__f)
|
||||
for (; __n > 0; --__n, ++__f)
|
||||
insert_equal_noresize(*__f);
|
||||
}
|
||||
|
||||
@@ -451,10 +459,10 @@ public:
|
||||
{
|
||||
size_type __n = _M_bkt_num_key(__key);
|
||||
_Node* __first;
|
||||
for ( __first = _M_buckets[__n];
|
||||
__first && !_M_equals(_M_get_key(__first->_M_val), __key);
|
||||
__first = __first->_M_next)
|
||||
{}
|
||||
for (__first = _M_buckets[__n];
|
||||
__first && !_M_equals(_M_get_key(__first->_M_val), __key);
|
||||
__first = __first->_M_next) {
|
||||
}
|
||||
return iterator(__first, this);
|
||||
}
|
||||
|
||||
@@ -462,10 +470,10 @@ public:
|
||||
{
|
||||
size_type __n = _M_bkt_num_key(__key);
|
||||
const _Node* __first;
|
||||
for ( __first = _M_buckets[__n];
|
||||
__first && !_M_equals(_M_get_key(__first->_M_val), __key);
|
||||
__first = __first->_M_next)
|
||||
{}
|
||||
for (__first = _M_buckets[__n];
|
||||
__first && !_M_equals(_M_get_key(__first->_M_val), __key);
|
||||
__first = __first->_M_next) {
|
||||
}
|
||||
return const_iterator(__first, this);
|
||||
}
|
||||
|
||||
@@ -480,11 +488,10 @@ public:
|
||||
return __result;
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& __key);
|
||||
std::pair<iterator, iterator> equal_range(const key_type& __key);
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& __key) const;
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
const key_type& __key) const;
|
||||
|
||||
size_type erase(const key_type& __key);
|
||||
void erase(const iterator& __it);
|
||||
@@ -497,14 +504,13 @@ public:
|
||||
void clear();
|
||||
|
||||
private:
|
||||
size_type _M_next_size(size_type __n) const
|
||||
{ return _stl_next_prime(__n); }
|
||||
size_type _M_next_size(size_type __n) const { return _stl_next_prime(__n); }
|
||||
|
||||
void _M_initialize_buckets(size_type __n)
|
||||
{
|
||||
const size_type __n_buckets = _M_next_size(__n);
|
||||
_M_buckets.reserve(__n_buckets);
|
||||
_M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
|
||||
_M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)0);
|
||||
_M_num_elements = 0;
|
||||
}
|
||||
|
||||
@@ -528,15 +534,12 @@ private:
|
||||
return _M_bkt_num_key(_M_get_key(__obj), __n);
|
||||
}
|
||||
|
||||
void construct(_Val* p, const _Val& v)
|
||||
{
|
||||
new (p) _Val(v);
|
||||
}
|
||||
void construct(_Val* p, const _Val& v) { new (p) _Val(v); }
|
||||
void destroy(_Val* p)
|
||||
{
|
||||
{
|
||||
(void)p;
|
||||
p->~_Val();
|
||||
}
|
||||
}
|
||||
|
||||
_Node* _M_new_node(const value_type& __obj)
|
||||
{
|
||||
@@ -545,8 +548,10 @@ private:
|
||||
try {
|
||||
construct(&__n->_M_val, __obj);
|
||||
return __n;
|
||||
} catch (...) {
|
||||
_M_put_node(__n);
|
||||
throw;
|
||||
}
|
||||
catch(...) {_M_put_node(__n); throw;}
|
||||
}
|
||||
|
||||
void _M_delete_node(_Node* __n)
|
||||
@@ -559,13 +564,12 @@ private:
|
||||
void _M_erase_bucket(const size_type __n, _Node* __last);
|
||||
|
||||
void _M_copy_from(const hashtable& __ht);
|
||||
|
||||
};
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
||||
class _All>
|
||||
_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
|
||||
_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
|
||||
_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
|
||||
_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
|
||||
{
|
||||
const _Node* __old = _M_cur;
|
||||
_M_cur = _M_cur->_M_next;
|
||||
@@ -579,8 +583,8 @@ _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
||||
class _All>
|
||||
inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
|
||||
_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
|
||||
inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
|
||||
_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
|
||||
{
|
||||
iterator __tmp = *this;
|
||||
++*this;
|
||||
@@ -589,8 +593,8 @@ _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
||||
class _All>
|
||||
_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
|
||||
_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
|
||||
_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
|
||||
_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
|
||||
{
|
||||
const _Node* __old = _M_cur;
|
||||
_M_cur = _M_cur->_M_next;
|
||||
@@ -604,8 +608,8 @@ _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
||||
class _All>
|
||||
inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
|
||||
_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
|
||||
inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
|
||||
_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
|
||||
{
|
||||
const_iterator __tmp = *this;
|
||||
++*this;
|
||||
@@ -613,18 +617,18 @@ _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
|
||||
const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
|
||||
bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
|
||||
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
|
||||
{
|
||||
typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
|
||||
typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
|
||||
if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
|
||||
return false;
|
||||
for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
|
||||
_Node* __cur1 = __ht1._M_buckets[__n];
|
||||
_Node* __cur2 = __ht2._M_buckets[__n];
|
||||
for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
|
||||
__cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
|
||||
{}
|
||||
for (; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
|
||||
__cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {
|
||||
}
|
||||
if (__cur1 || __cur2)
|
||||
return false;
|
||||
}
|
||||
@@ -632,22 +636,24 @@ bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
|
||||
const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
|
||||
inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
|
||||
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
|
||||
{
|
||||
return !(__ht1 == __ht2);
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
|
||||
class _All>
|
||||
inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
|
||||
hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
|
||||
hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
|
||||
{
|
||||
__ht1.swap(__ht2);
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::insert_unique_noresize(const value_type& __obj)
|
||||
std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
|
||||
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_unique_noresize(
|
||||
const value_type& __obj)
|
||||
{
|
||||
const size_type __n = _M_bkt_num(__obj);
|
||||
_Node* __first = _M_buckets[__n];
|
||||
@@ -664,9 +670,9 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::insert_equal_noresize(const value_type& __obj)
|
||||
typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
|
||||
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_equal_noresize(
|
||||
const value_type& __obj)
|
||||
{
|
||||
const size_type __n = _M_bkt_num(__obj);
|
||||
_Node* __first = _M_buckets[__n];
|
||||
@@ -688,8 +694,8 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
|
||||
typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference hashtable<
|
||||
_Val, _Key, _HF, _Ex, _Eq, _All>::find_or_insert(const value_type& __obj)
|
||||
{
|
||||
resize(_M_num_elements + 1);
|
||||
|
||||
@@ -708,9 +714,9 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
|
||||
typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
|
||||
std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
|
||||
typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
|
||||
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key)
|
||||
{
|
||||
typedef std::pair<iterator, iterator> _Pii;
|
||||
const size_type __n = _M_bkt_num_key(__key);
|
||||
@@ -723,27 +729,25 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
|
||||
for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
|
||||
if (_M_buckets[__m])
|
||||
return _Pii(iterator(__first, this),
|
||||
iterator(_M_buckets[__m], this));
|
||||
iterator(_M_buckets[__m], this));
|
||||
return _Pii(iterator(__first, this), end());
|
||||
}
|
||||
return _Pii(end(), end());
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
|
||||
typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::equal_range(const key_type& __key) const
|
||||
std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
|
||||
typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
|
||||
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(
|
||||
const key_type& __key) const
|
||||
{
|
||||
typedef std::pair<const_iterator, const_iterator> _Pii;
|
||||
const size_type __n = _M_bkt_num_key(__key);
|
||||
|
||||
for (const _Node* __first = _M_buckets[__n] ;
|
||||
__first;
|
||||
for (const _Node* __first = _M_buckets[__n]; __first;
|
||||
__first = __first->_M_next) {
|
||||
if (_M_equals(_M_get_key(__first->_M_val), __key)) {
|
||||
for (const _Node* __cur = __first->_M_next;
|
||||
__cur;
|
||||
for (const _Node* __cur = __first->_M_next; __cur;
|
||||
__cur = __cur->_M_next)
|
||||
if (!_M_equals(_M_get_key(__cur->_M_val), __key))
|
||||
return _Pii(const_iterator(__first, this),
|
||||
@@ -759,8 +763,8 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
|
||||
typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
|
||||
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key)
|
||||
{
|
||||
const size_type __n = _M_bkt_num_key(__key);
|
||||
_Node* __first = _M_buckets[__n];
|
||||
@@ -776,8 +780,7 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
|
||||
__next = __cur->_M_next;
|
||||
++__erased;
|
||||
--_M_num_elements;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
__cur = __next;
|
||||
__next = __cur->_M_next;
|
||||
}
|
||||
@@ -793,7 +796,7 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it)
|
||||
{
|
||||
_Node* __p = __it._M_cur;
|
||||
if (__p) {
|
||||
@@ -804,8 +807,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
|
||||
_M_buckets[__n] = __cur->_M_next;
|
||||
_M_delete_node(__cur);
|
||||
--_M_num_elements;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
_Node* __next = __cur->_M_next;
|
||||
while (__next) {
|
||||
if (__next == __p) {
|
||||
@@ -813,8 +815,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
|
||||
_M_delete_node(__next);
|
||||
--_M_num_elements;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
__cur = __next;
|
||||
__next = __cur->_M_next;
|
||||
}
|
||||
@@ -824,13 +825,13 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::erase(iterator __first, iterator __last)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first,
|
||||
iterator __last)
|
||||
{
|
||||
size_type __f_bucket = __first._M_cur ?
|
||||
_M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
|
||||
size_type __l_bucket = __last._M_cur ?
|
||||
_M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
|
||||
size_type __f_bucket =
|
||||
__first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
|
||||
size_type __l_bucket =
|
||||
__last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
|
||||
|
||||
if (__first._M_cur == __last._M_cur)
|
||||
return;
|
||||
@@ -846,9 +847,8 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
inline void
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
|
||||
const_iterator __last)
|
||||
inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
|
||||
const_iterator __first, const_iterator __last)
|
||||
{
|
||||
erase(iterator(const_cast<_Node*>(__first._M_cur),
|
||||
const_cast<hashtable*>(__first._M_ht)),
|
||||
@@ -857,24 +857,22 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
inline void
|
||||
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
|
||||
inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
|
||||
const const_iterator& __it)
|
||||
{
|
||||
erase(iterator(const_cast<_Node*>(__it._M_cur),
|
||||
const_cast<hashtable*>(__it._M_ht)));
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::resize(size_type __num_elements_hint)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(
|
||||
size_type __num_elements_hint)
|
||||
{
|
||||
const size_type __old_n = _M_buckets.size();
|
||||
if (__num_elements_hint > __old_n) {
|
||||
const size_type __n = _M_next_size(__num_elements_hint);
|
||||
if (__n > __old_n) {
|
||||
_M_buckets_type __tmp(
|
||||
__n, (_Node*)(0),
|
||||
_M_buckets.get_allocator());
|
||||
_M_buckets_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
|
||||
try {
|
||||
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
|
||||
_Node* __first = _M_buckets[__bucket];
|
||||
@@ -887,8 +885,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
}
|
||||
_M_buckets.swap(__tmp);
|
||||
}
|
||||
catch(...) {
|
||||
} catch (...) {
|
||||
for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
|
||||
while (__tmp[__bucket]) {
|
||||
_Node* __next = __tmp[__bucket]->_M_next;
|
||||
@@ -903,16 +900,15 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
|
||||
const size_type __n, _Node* __first, _Node* __last)
|
||||
{
|
||||
_Node* __cur = _M_buckets[__n];
|
||||
if (__cur == __first)
|
||||
_M_erase_bucket(__n, __last);
|
||||
else {
|
||||
_Node* __next;
|
||||
for (__next = __cur->_M_next;
|
||||
__next != __first;
|
||||
for (__next = __cur->_M_next; __next != __first;
|
||||
__cur = __next, __next = __cur->_M_next)
|
||||
;
|
||||
while (__next != __last) {
|
||||
@@ -925,8 +921,8 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::_M_erase_bucket(const size_type __n, _Node* __last)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
|
||||
const size_type __n, _Node* __last)
|
||||
{
|
||||
_Node* __cur = _M_buckets[__n];
|
||||
while (__cur != __last) {
|
||||
@@ -939,7 +935,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear()
|
||||
{
|
||||
for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
|
||||
_Node* __cur = _M_buckets[__i];
|
||||
@@ -953,14 +949,13 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
|
||||
_M_num_elements = 0;
|
||||
}
|
||||
|
||||
|
||||
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
|
||||
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
::_M_copy_from(const hashtable& __ht)
|
||||
void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(
|
||||
const hashtable& __ht)
|
||||
{
|
||||
_M_buckets.clear();
|
||||
_M_buckets.reserve(__ht._M_buckets.size());
|
||||
_M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
|
||||
_M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)0);
|
||||
try {
|
||||
for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
|
||||
const _Node* __cur = __ht._M_buckets[__i];
|
||||
@@ -968,8 +963,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
_Node* __copy = _M_new_node(__cur->_M_val);
|
||||
_M_buckets[__i] = __copy;
|
||||
|
||||
for (_Node* __next = __cur->_M_next;
|
||||
__next;
|
||||
for (_Node *__next = __cur->_M_next; __next;
|
||||
__cur = __next, __next = __cur->_M_next) {
|
||||
__copy->_M_next = _M_new_node(__next->_M_val);
|
||||
__copy = __copy->_M_next;
|
||||
@@ -977,21 +971,23 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
|
||||
}
|
||||
}
|
||||
_M_num_elements = __ht._M_num_elements;
|
||||
} catch (...) {
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
catch(...) {clear(); throw;}
|
||||
}
|
||||
|
||||
} // namespace @KWSYS_NAMESPACE@
|
||||
|
||||
// Undo warning suppression.
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
# if __has_warning("-Wdeprecated")
|
||||
# pragma clang diagnostic pop
|
||||
# endif
|
||||
#if __has_warning("-Wdeprecated")
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
#=============================================================================
|
||||
# KWSys - Kitware System Library
|
||||
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
|
||||
|
||||
if ( $#ARGV+1 < 2 )
|
||||
{
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
#=============================================================================
|
||||
# KWSys - Kitware System Library
|
||||
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
|
||||
|
||||
SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
|
||||
SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
/*
|
||||
Macros to define main() in a cross-platform way.
|
||||
|
||||
@@ -26,21 +17,23 @@
|
||||
}
|
||||
*/
|
||||
#if defined(__CLASSIC_C__)
|
||||
# define KWSYS_PLATFORM_TEST_C_MAIN() \
|
||||
main()
|
||||
# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
|
||||
main(argc,argv) int argc; char* argv[];
|
||||
#define KWSYS_PLATFORM_TEST_C_MAIN() main()
|
||||
#define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
|
||||
main(argc, argv) int argc; \
|
||||
char* argv[];
|
||||
#else
|
||||
# define KWSYS_PLATFORM_TEST_C_MAIN() \
|
||||
main(void)
|
||||
# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
|
||||
#define KWSYS_PLATFORM_TEST_C_MAIN() main(void)
|
||||
#define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
|
||||
main(int argc, char* argv[])
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifdef TEST_KWSYS_C_HAS_PTRDIFF_T
|
||||
#include <stddef.h>
|
||||
int f(ptrdiff_t n) { return n > 0; }
|
||||
int f(ptrdiff_t n)
|
||||
{
|
||||
return n > 0;
|
||||
}
|
||||
int KWSYS_PLATFORM_TEST_C_MAIN()
|
||||
{
|
||||
char* p = 0;
|
||||
@@ -53,7 +46,10 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifdef TEST_KWSYS_C_HAS_SSIZE_T
|
||||
#include <unistd.h>
|
||||
int f(ssize_t n) { return (int)n; }
|
||||
int f(ssize_t n)
|
||||
{
|
||||
return (int)n;
|
||||
}
|
||||
int KWSYS_PLATFORM_TEST_C_MAIN()
|
||||
{
|
||||
ssize_t n = 0;
|
||||
@@ -65,28 +61,28 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
|
||||
#ifdef TEST_KWSYS_C_TYPE_MACROS
|
||||
char* info_macros =
|
||||
#if defined(__SIZEOF_SHORT__)
|
||||
"INFO:macro[__SIZEOF_SHORT__]\n"
|
||||
"INFO:macro[__SIZEOF_SHORT__]\n"
|
||||
#endif
|
||||
#if defined(__SIZEOF_INT__)
|
||||
"INFO:macro[__SIZEOF_INT__]\n"
|
||||
"INFO:macro[__SIZEOF_INT__]\n"
|
||||
#endif
|
||||
#if defined(__SIZEOF_LONG__)
|
||||
"INFO:macro[__SIZEOF_LONG__]\n"
|
||||
"INFO:macro[__SIZEOF_LONG__]\n"
|
||||
#endif
|
||||
#if defined(__SIZEOF_LONG_LONG__)
|
||||
"INFO:macro[__SIZEOF_LONG_LONG__]\n"
|
||||
"INFO:macro[__SIZEOF_LONG_LONG__]\n"
|
||||
#endif
|
||||
#if defined(__SHORT_MAX__)
|
||||
"INFO:macro[__SHORT_MAX__]\n"
|
||||
"INFO:macro[__SHORT_MAX__]\n"
|
||||
#endif
|
||||
#if defined(__INT_MAX__)
|
||||
"INFO:macro[__INT_MAX__]\n"
|
||||
"INFO:macro[__INT_MAX__]\n"
|
||||
#endif
|
||||
#if defined(__LONG_MAX__)
|
||||
"INFO:macro[__LONG_MAX__]\n"
|
||||
"INFO:macro[__LONG_MAX__]\n"
|
||||
#endif
|
||||
#if defined(__LONG_LONG_MAX__)
|
||||
"INFO:macro[__LONG_LONG_MAX__]\n"
|
||||
"INFO:macro[__LONG_LONG_MAX__]\n"
|
||||
#endif
|
||||
"";
|
||||
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifdef TEST_KWSYS_CXX_HAS_CSTDIO
|
||||
#include <cstdio>
|
||||
int main() { return 0; }
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
|
||||
long long f(long long n) { return n; }
|
||||
long long f(long long n)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
long long n = 0;
|
||||
@@ -24,7 +21,10 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS___INT64
|
||||
__int64 f(__int64 n) { return n; }
|
||||
__int64 f(__int64 n)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
__int64 n = 0;
|
||||
@@ -34,6 +34,7 @@ int main()
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIM
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
int main()
|
||||
@@ -47,6 +48,7 @@ int main()
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
int main()
|
||||
@@ -59,7 +61,9 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
|
||||
void function(long**) {}
|
||||
void function(long**)
|
||||
{
|
||||
}
|
||||
int main()
|
||||
{
|
||||
__int64** p = 0;
|
||||
@@ -69,7 +73,9 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64
|
||||
void function(long long**) {}
|
||||
void function(long long**)
|
||||
{
|
||||
}
|
||||
int main()
|
||||
{
|
||||
__int64** p = 0;
|
||||
@@ -79,10 +85,10 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
|
||||
# include <iostream>
|
||||
#include <iostream>
|
||||
int test_istream(std::istream& is, long long& x)
|
||||
{
|
||||
return (is >> x)? 1:0;
|
||||
return (is >> x) ? 1 : 0;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
@@ -92,10 +98,10 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
|
||||
# include <iostream>
|
||||
#include <iostream>
|
||||
int test_ostream(std::ostream& os, long long x)
|
||||
{
|
||||
return (os << x)? 1:0;
|
||||
return (os << x) ? 1 : 0;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
@@ -105,10 +111,10 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
|
||||
# include <iostream>
|
||||
#include <iostream>
|
||||
int test_istream(std::istream& is, __int64& x)
|
||||
{
|
||||
return (is >> x)? 1:0;
|
||||
return (is >> x) ? 1 : 0;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
@@ -118,10 +124,10 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
|
||||
# include <iostream>
|
||||
#include <iostream>
|
||||
int test_ostream(std::ostream& os, __int64 x)
|
||||
{
|
||||
return (os << x)? 1:0;
|
||||
return (os << x) ? 1 : 0;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
@@ -137,30 +143,31 @@ int main()
|
||||
#define _LARGE_FILES
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#if KWSYS_CXX_HAS_CSTDIO
|
||||
# include <cstdio>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int, char **argv)
|
||||
int main(int, char** argv)
|
||||
{
|
||||
/* check that off_t can hold 2^63 - 1 and perform basic operations... */
|
||||
#define OFF_T_64 (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
/* check that off_t can hold 2^63 - 1 and perform basic operations... */
|
||||
#define OFF_T_64 (((off_t)1 << 62) - 1 + ((off_t)1 << 62))
|
||||
if (OFF_T_64 % 2147483647 != 1)
|
||||
return 1;
|
||||
|
||||
// stat breaks on SCO OpenServer
|
||||
struct stat buf;
|
||||
stat( argv[0], &buf );
|
||||
stat(argv[0], &buf);
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
return 2;
|
||||
|
||||
FILE *file = fopen( argv[0], "r" );
|
||||
off_t offset = ftello( file );
|
||||
fseek( file, offset, SEEK_CUR );
|
||||
fclose( file );
|
||||
FILE* file = fopen(argv[0], "r");
|
||||
off_t offset = ftello(file);
|
||||
fseek(file, offset, SEEK_CUR);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -187,14 +194,14 @@ int main()
|
||||
int main()
|
||||
{
|
||||
char* e = environ[0];
|
||||
return e? 0:1;
|
||||
return e ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
|
||||
// Match feature definitions from SystemInformation.cxx
|
||||
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
int main()
|
||||
@@ -205,17 +212,17 @@ int main()
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
|
||||
# if defined(KWSYS_HAS_LFS)
|
||||
# define _LARGEFILE_SOURCE
|
||||
# define _LARGEFILE64_SOURCE
|
||||
# define _LARGE_FILES
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
# endif
|
||||
# include <sys/resource.h>
|
||||
#if defined(KWSYS_HAS_LFS)
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _LARGE_FILES
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
#include <sys/resource.h>
|
||||
int main()
|
||||
{
|
||||
struct rlimit64 rlim;
|
||||
return getrlimit64(0,&rlim);
|
||||
return getrlimit64(0, &rlim);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -223,7 +230,7 @@ int main()
|
||||
#include <stdlib.h>
|
||||
int main()
|
||||
{
|
||||
const char *str="1024";
|
||||
const char* str = "1024";
|
||||
return static_cast<int>(atoll(str));
|
||||
}
|
||||
#endif
|
||||
@@ -232,7 +239,7 @@ int main()
|
||||
#include <stdlib.h>
|
||||
int main()
|
||||
{
|
||||
const char *str="1024";
|
||||
const char* str = "1024";
|
||||
return static_cast<int>(atol(str));
|
||||
}
|
||||
#endif
|
||||
@@ -241,7 +248,7 @@ int main()
|
||||
#include <stdlib.h>
|
||||
int main()
|
||||
{
|
||||
const char *str="1024";
|
||||
const char* str = "1024";
|
||||
return static_cast<int>(_atoi64(str));
|
||||
}
|
||||
#endif
|
||||
@@ -260,58 +267,58 @@ int main()
|
||||
#include <sys/stat.h>
|
||||
int main()
|
||||
{
|
||||
struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}};
|
||||
struct timespec times[2] = { { 0, UTIME_OMIT }, { 0, UTIME_NOW } };
|
||||
return utimensat(AT_FDCWD, "/example", times, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_BACKTRACE
|
||||
#if defined(__PATHSCALE__) || defined(__PATHCC__) \
|
||||
|| (defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41))
|
||||
#if defined(__PATHSCALE__) || defined(__PATHCC__) || \
|
||||
(defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41))
|
||||
backtrace doesnt work with this compiler or os
|
||||
#endif
|
||||
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <execinfo.h>
|
||||
int main()
|
||||
{
|
||||
void *stackSymbols[256];
|
||||
backtrace(stackSymbols,256);
|
||||
backtrace_symbols(&stackSymbols[0],1);
|
||||
void* stackSymbols[256];
|
||||
backtrace(stackSymbols, 256);
|
||||
backtrace_symbols(&stackSymbols[0], 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_DLADDR
|
||||
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
int main()
|
||||
{
|
||||
Dl_info info;
|
||||
int ierr=dladdr((void*)main,&info);
|
||||
int ierr = dladdr((void*)main, &info);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_CXXABI
|
||||
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 \
|
||||
&& __linux && __SUNPRO_CC_COMPAT == 'G'
|
||||
# include <iostream>
|
||||
#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 && __linux && \
|
||||
__SUNPRO_CC_COMPAT == 'G'
|
||||
#include <iostream>
|
||||
#endif
|
||||
#include <cxxabi.h>
|
||||
int main()
|
||||
{
|
||||
int status = 0;
|
||||
size_t bufferLen = 512;
|
||||
char buffer[512] = {'\0'};
|
||||
const char *function="_ZN5kwsys17SystemInformation15GetProgramStackEii";
|
||||
char *demangledFunction =
|
||||
char buffer[512] = { '\0' };
|
||||
const char* function = "_ZN5kwsys17SystemInformation15GetProgramStackEii";
|
||||
char* demangledFunction =
|
||||
abi::__cxa_demangle(function, buffer, &bufferLen, &status);
|
||||
return status;
|
||||
}
|
||||
@@ -346,11 +353,19 @@ int main()
|
||||
|
||||
#ifdef TEST_KWSYS_STL_HAS_WSTRING
|
||||
#include <string>
|
||||
void f(std ::wstring*) {}
|
||||
int main() { return 0; }
|
||||
void f(std::wstring*)
|
||||
{
|
||||
}
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H
|
||||
#include <ext/stdio_filebuf.h>
|
||||
int main() { return 0; }
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1,16 +1,7 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef KWSYS_NAMESPACE
|
||||
# error "Do not include kwsysPrivate.h outside of kwsys c and cxx files."
|
||||
#error "Do not include kwsysPrivate.h outside of kwsys c and cxx files."
|
||||
#endif
|
||||
|
||||
#ifndef _kwsysPrivate_h
|
||||
@@ -24,7 +15,9 @@
|
||||
#include KWSYS_HEADER(Directory.hxx)
|
||||
#include KWSYS_HEADER(std/vector)
|
||||
*/
|
||||
/* clang-format off */
|
||||
#define KWSYS_HEADER(x) KWSYS_HEADER0(KWSYS_NAMESPACE/x)
|
||||
/* clang-format on */
|
||||
#define KWSYS_HEADER0(x) KWSYS_HEADER1(x)
|
||||
#define KWSYS_HEADER1(x) <x>
|
||||
|
||||
@@ -37,5 +30,5 @@
|
||||
#define KWSYS_NAMESPACE_STRING1(x) #x
|
||||
|
||||
#else
|
||||
# error "kwsysPrivate.h included multiple times."
|
||||
#error "kwsysPrivate.h included multiple times."
|
||||
#endif
|
||||
@@ -1,21 +1,12 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(CommandLineArguments.hxx)
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "CommandLineArguments.hxx.in"
|
||||
#include "CommandLineArguments.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@@ -28,33 +19,45 @@ static void* random_ptr = reinterpret_cast<void*>(0x123);
|
||||
|
||||
static int argument(const char* arg, const char* value, void* call_data)
|
||||
{
|
||||
std::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << std::endl;
|
||||
if ( call_data != random_ptr )
|
||||
{
|
||||
std::cout << "Got argument: \"" << arg << "\" value: \""
|
||||
<< (value ? value : "(null)") << "\"" << std::endl;
|
||||
if (call_data != random_ptr) {
|
||||
std::cerr << "Problem processing call_data" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int unknown_argument(const char* argument, void* call_data)
|
||||
{
|
||||
std::cout << "Got unknown argument: \"" << argument << "\"" << std::endl;
|
||||
if ( call_data != random_ptr )
|
||||
{
|
||||
if (call_data != random_ptr) {
|
||||
std::cerr << "Problem processing call_data" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(const char* i1,
|
||||
const char* i2) { return strcmp(i1, i2) == 0; }
|
||||
static bool CompareTwoItemsOnList(const std::string& i1,
|
||||
const std::string& i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(bool i1, bool i2)
|
||||
{
|
||||
return i1 == i2;
|
||||
}
|
||||
static bool CompareTwoItemsOnList(int i1, int i2)
|
||||
{
|
||||
return i1 == i2;
|
||||
}
|
||||
static bool CompareTwoItemsOnList(double i1, double i2)
|
||||
{
|
||||
return i1 == i2;
|
||||
}
|
||||
static bool CompareTwoItemsOnList(const char* i1, const char* i2)
|
||||
{
|
||||
return strcmp(i1, i2) == 0;
|
||||
}
|
||||
static bool CompareTwoItemsOnList(const std::string& i1, const std::string& i2)
|
||||
{
|
||||
return i1 == i2;
|
||||
}
|
||||
|
||||
int testCommandLineArguments(int argc, char* argv[])
|
||||
{
|
||||
@@ -97,73 +100,89 @@ int testCommandLineArguments(int argc, char* argv[])
|
||||
|
||||
typedef kwsys::CommandLineArguments argT;
|
||||
|
||||
arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, &some_int_variable, "Set some random int variable");
|
||||
arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT, &some_double_variable, "Set some random double variable");
|
||||
arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT, &some_string_variable, "Set some random string variable");
|
||||
arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT, &some_stl_string_variable, "Set some random stl string variable");
|
||||
arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT, &some_bool_variable, "Set some random bool variable");
|
||||
arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, &some_bool_variable1, "Set some random bool variable 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, "Test AddBooleanArgument 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, "Test AddBooleanArgument 2");
|
||||
arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT, &numbers_argument, "Some multiple values variable");
|
||||
arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT,
|
||||
&some_int_variable, "Set some random int variable");
|
||||
arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT,
|
||||
&some_double_variable, "Set some random double variable");
|
||||
arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT,
|
||||
&some_string_variable, "Set some random string variable");
|
||||
arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT,
|
||||
&some_stl_string_variable,
|
||||
"Set some random stl string variable");
|
||||
arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT,
|
||||
&some_bool_variable, "Set some random bool variable");
|
||||
arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT,
|
||||
&some_bool_variable1, "Set some random bool variable 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1,
|
||||
"Test AddBooleanArgument 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2,
|
||||
"Test AddBooleanArgument 2");
|
||||
arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT,
|
||||
&numbers_argument, "Some multiple values variable");
|
||||
arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument,
|
||||
"Some explicit multiple values variable");
|
||||
arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument,
|
||||
"Some explicit multiple values variable");
|
||||
arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument,
|
||||
"Some explicit multiple values variable");
|
||||
arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument,
|
||||
"Some explicit multiple values variable");
|
||||
|
||||
arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, "Some option -A. This option has a multiline comment. It should demonstrate how the code splits lines.");
|
||||
arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, "Option -B takes argument with space");
|
||||
arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr, "Option -C takes argument after =");
|
||||
arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr, "This option takes concatinated argument");
|
||||
arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr,
|
||||
"Some option -A. This option has a multiline comment. It "
|
||||
"should demonstrate how the code splits lines.");
|
||||
arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr,
|
||||
"Option -B takes argument with space");
|
||||
arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr,
|
||||
"Option -C takes argument after =");
|
||||
arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr,
|
||||
"This option takes concatinated argument");
|
||||
arg.AddCallback("--long1", argT::NO_ARGUMENT, argument, random_ptr, "-A");
|
||||
arg.AddCallback("--long2", argT::SPACE_ARGUMENT, argument, random_ptr, "-B");
|
||||
arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr, "Same as -C but a bit different");
|
||||
arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr, "-C");
|
||||
arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr,
|
||||
"Same as -C but a bit different");
|
||||
arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr,
|
||||
"-C");
|
||||
|
||||
if ( !arg.Parse() )
|
||||
{
|
||||
if (!arg.Parse()) {
|
||||
std::cerr << "Problem parsing arguments" << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
std::cout << "Help: " << arg.GetHelp() << std::endl;
|
||||
|
||||
std::cout << "Some int variable was set to: " << some_int_variable << std::endl;
|
||||
std::cout << "Some double variable was set to: " << some_double_variable << std::endl;
|
||||
if ( some_string_variable && strcmp(some_string_variable, "test string with space") == 0)
|
||||
{
|
||||
std::cout << "Some string variable was set to: " << some_string_variable << std::endl;
|
||||
delete [] some_string_variable;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Some int variable was set to: " << some_int_variable
|
||||
<< std::endl;
|
||||
std::cout << "Some double variable was set to: " << some_double_variable
|
||||
<< std::endl;
|
||||
if (some_string_variable &&
|
||||
strcmp(some_string_variable, "test string with space") == 0) {
|
||||
std::cout << "Some string variable was set to: " << some_string_variable
|
||||
<< std::endl;
|
||||
delete[] some_string_variable;
|
||||
} else {
|
||||
std::cerr << "Problem setting string variable" << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
size_t cc;
|
||||
#define CompareTwoLists(list1, list_valid, lsize) \
|
||||
if ( list1.size() != lsize ) \
|
||||
{ \
|
||||
std::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
|
||||
<< " should be: " << lsize << std::endl; \
|
||||
res = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
std::cout << #list1 " argument set:"; \
|
||||
for ( cc =0; cc < lsize; ++ cc ) \
|
||||
{ \
|
||||
std::cout << " " << list1[cc]; \
|
||||
if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \
|
||||
{ \
|
||||
std::cerr << "Problem setting " #list1 ". Value of " \
|
||||
<< cc << " is: [" << list1[cc] << "] <> [" \
|
||||
<< list_valid[cc] << "]" << std::endl; \
|
||||
res = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
std::cout << std::endl; \
|
||||
}
|
||||
#define CompareTwoLists(list1, list_valid, lsize) \
|
||||
if (list1.size() != lsize) { \
|
||||
std::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
|
||||
<< " should be: " << lsize << std::endl; \
|
||||
res = 1; \
|
||||
} else { \
|
||||
std::cout << #list1 " argument set:"; \
|
||||
for (cc = 0; cc < lsize; ++cc) { \
|
||||
std::cout << " " << list1[cc]; \
|
||||
if (!CompareTwoItemsOnList(list1[cc], list_valid[cc])) { \
|
||||
std::cerr << "Problem setting " #list1 ". Value of " << cc \
|
||||
<< " is: [" << list1[cc] << "] <> [" << list_valid[cc] \
|
||||
<< "]" << std::endl; \
|
||||
res = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
std::cout << std::endl; \
|
||||
}
|
||||
|
||||
CompareTwoLists(numbers_argument, valid_numbers, 10);
|
||||
CompareTwoLists(doubles_argument, valid_doubles, 3);
|
||||
@@ -171,17 +190,19 @@ int testCommandLineArguments(int argc, char* argv[])
|
||||
CompareTwoLists(strings_argument, valid_strings, 4);
|
||||
CompareTwoLists(stl_strings_argument, valid_stl_strings, 4);
|
||||
|
||||
std::cout << "Some STL String variable was set to: " << some_stl_string_variable << std::endl;
|
||||
std::cout << "Some bool variable was set to: " << some_bool_variable << std::endl;
|
||||
std::cout << "Some bool variable was set to: " << some_bool_variable1 << std::endl;
|
||||
std::cout << "Some STL String variable was set to: "
|
||||
<< some_stl_string_variable << std::endl;
|
||||
std::cout << "Some bool variable was set to: " << some_bool_variable
|
||||
<< std::endl;
|
||||
std::cout << "Some bool variable was set to: " << some_bool_variable1
|
||||
<< std::endl;
|
||||
std::cout << "bool_arg1 variable was set to: " << bool_arg1 << std::endl;
|
||||
std::cout << "bool_arg2 variable was set to: " << bool_arg2 << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
for ( cc = 0; cc < strings_argument.size(); ++ cc )
|
||||
{
|
||||
delete [] strings_argument[cc];
|
||||
for (cc = 0; cc < strings_argument.size(); ++cc) {
|
||||
delete[] strings_argument[cc];
|
||||
strings_argument[cc] = 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -1,21 +1,12 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(CommandLineArguments.hxx)
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "CommandLineArguments.hxx.in"
|
||||
#include "CommandLineArguments.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@@ -41,68 +32,62 @@ int testCommandLineArguments1(int argc, char* argv[])
|
||||
|
||||
arg.StoreUnusedArguments(true);
|
||||
|
||||
if ( !arg.Parse() )
|
||||
{
|
||||
if (!arg.Parse()) {
|
||||
std::cerr << "Problem parsing arguments" << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
if ( n != 24 )
|
||||
{
|
||||
}
|
||||
if (n != 24) {
|
||||
std::cout << "Problem setting N. Value of N: " << n << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
if ( !m || strcmp(m, "test value") != 0 )
|
||||
{
|
||||
}
|
||||
if (!m || strcmp(m, "test value") != 0) {
|
||||
std::cout << "Problem setting M. Value of M: " << m << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
if ( p != "1" )
|
||||
{
|
||||
}
|
||||
if (p != "1") {
|
||||
std::cout << "Problem setting P. Value of P: " << p << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
std::cout << "Value of N: " << n << std::endl;
|
||||
std::cout << "Value of M: " << m << std::endl;
|
||||
std::cout << "Value of P: " << p << std::endl;
|
||||
if ( m )
|
||||
{
|
||||
delete [] m;
|
||||
}
|
||||
if (m) {
|
||||
delete[] m;
|
||||
}
|
||||
|
||||
char** newArgv = 0;
|
||||
int newArgc = 0;
|
||||
arg.GetUnusedArguments(&newArgc, &newArgv);
|
||||
int cc;
|
||||
const char* valid_unused_args[9] = {
|
||||
0, "--ignored", "--second-ignored", "third-ignored",
|
||||
"some", "junk", "at", "the", "end"
|
||||
};
|
||||
if ( newArgc != 9 )
|
||||
{
|
||||
const char* valid_unused_args[9] = { 0,
|
||||
"--ignored",
|
||||
"--second-ignored",
|
||||
"third-ignored",
|
||||
"some",
|
||||
"junk",
|
||||
"at",
|
||||
"the",
|
||||
"end" };
|
||||
if (newArgc != 9) {
|
||||
std::cerr << "Bad number of unused arguments: " << newArgc << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
for ( cc = 0; cc < newArgc; ++ cc )
|
||||
{
|
||||
}
|
||||
for (cc = 0; cc < newArgc; ++cc) {
|
||||
assert(newArgv[cc]); /* Quiet Clang scan-build. */
|
||||
std::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
|
||||
<< std::endl;
|
||||
if ( cc >= 9 )
|
||||
{
|
||||
<< std::endl;
|
||||
if (cc >= 9) {
|
||||
std::cerr << "Too many unused arguments: " << cc << std::endl;
|
||||
res = 1;
|
||||
}
|
||||
else if ( valid_unused_args[cc] &&
|
||||
strcmp(valid_unused_args[cc], newArgv[cc]) != 0 )
|
||||
{
|
||||
std::cerr << "Bad unused argument [" << cc << "] \""
|
||||
<< newArgv[cc] << "\" should be: \"" << valid_unused_args[cc] << "\""
|
||||
<< std::endl;
|
||||
} else if (valid_unused_args[cc] &&
|
||||
strcmp(valid_unused_args[cc], newArgv[cc]) != 0) {
|
||||
std::cerr << "Bad unused argument [" << cc << "] \"" << newArgv[cc]
|
||||
<< "\" should be: \"" << valid_unused_args[cc] << "\""
|
||||
<< std::endl;
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
arg.DeleteRemainingArguments(newArgc, &newArgv);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
+233
-179
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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"
|
||||
|
||||
// Ignore Windows version levels defined by command-line flags. This
|
||||
@@ -22,24 +13,26 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Encoding.hxx.in"
|
||||
#include "Encoding.hxx.in"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <stdexcept>
|
||||
#include <windows.h>
|
||||
|
||||
#include "testConsoleBuf.hxx"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
# define KWSYS_WINDOWS_DEPRECATED_GetVersion
|
||||
#define KWSYS_WINDOWS_DEPRECATED_GetVersion
|
||||
#endif
|
||||
// يونيكود
|
||||
static const WCHAR UnicodeInputTestString[] = L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
|
||||
static const WCHAR UnicodeInputTestString[] =
|
||||
L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
|
||||
static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE;
|
||||
|
||||
static const DWORD waitTimeout = 10 * 1000;
|
||||
@@ -50,55 +43,62 @@ static HANDLE afterOutputEvent;
|
||||
static std::string encodedInputTestString;
|
||||
static std::string encodedTestString;
|
||||
|
||||
static void displayError(DWORD errorCode) {
|
||||
static void displayError(DWORD errorCode)
|
||||
{
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl;
|
||||
LPWSTR message;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
errorCode,
|
||||
0,
|
||||
(LPWSTR)&message, 0,
|
||||
NULL)
|
||||
) {
|
||||
std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, errorCode, 0, (LPWSTR)&message, 0, NULL)) {
|
||||
std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message)
|
||||
<< std::endl;
|
||||
HeapFree(GetProcessHeap(), 0, message);
|
||||
} else {
|
||||
std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() << "!" << std::endl;
|
||||
std::cerr << "FormatMessage() failed with error: 0x" << GetLastError()
|
||||
<< "!" << std::endl;
|
||||
}
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
}
|
||||
|
||||
std::basic_streambuf<char> *errstream(const char *unused) {
|
||||
std::basic_streambuf<char>* errstream(const char* unused)
|
||||
{
|
||||
static_cast<void>(unused);
|
||||
return std::cerr.rdbuf();
|
||||
}
|
||||
|
||||
std::basic_streambuf<wchar_t> *errstream(const wchar_t *unused) {
|
||||
std::basic_streambuf<wchar_t>* errstream(const wchar_t* unused)
|
||||
{
|
||||
static_cast<void>(unused);
|
||||
return std::wcerr.rdbuf();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
static void dumpBuffers(const T *expected, const T *received, size_t size) {
|
||||
template <typename T>
|
||||
static void dumpBuffers(const T* expected, const T* received, size_t size)
|
||||
{
|
||||
std::basic_ostream<T> err(errstream(expected));
|
||||
err << "Expected output: '" << std::basic_string<T>(expected, size) << "'" << std::endl;
|
||||
err << "Expected output: '" << std::basic_string<T>(expected, size) << "'"
|
||||
<< std::endl;
|
||||
if (err.fail()) {
|
||||
err.clear();
|
||||
err << "--- Error while outputting ---" << std::endl;
|
||||
}
|
||||
err << "Received output: '" << std::basic_string<T>(received, size) << "'" << std::endl;
|
||||
err << "Received output: '" << std::basic_string<T>(received, size) << "'"
|
||||
<< std::endl;
|
||||
if (err.fail()) {
|
||||
err.clear();
|
||||
err << "--- Error while outputting ---" << std::endl;
|
||||
}
|
||||
std::cerr << "Expected output | Received output" << std::endl;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
std::cerr << std::setbase(16) << std::setfill('0') << " " <<
|
||||
"0x" << std::setw(8) << static_cast<unsigned int>(expected[i]) << " | " <<
|
||||
"0x" << std::setw(8) << static_cast<unsigned int>(received[i]);
|
||||
if (static_cast<unsigned int>(expected[i]) != static_cast<unsigned int>(received[i])) {
|
||||
std::cerr << std::setbase(16) << std::setfill('0') << " "
|
||||
<< "0x" << std::setw(8) << static_cast<unsigned int>(expected[i])
|
||||
<< " | "
|
||||
<< "0x" << std::setw(8)
|
||||
<< static_cast<unsigned int>(received[i]);
|
||||
if (static_cast<unsigned int>(expected[i]) !=
|
||||
static_cast<unsigned int>(received[i])) {
|
||||
std::cerr << " MISMATCH!";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
@@ -129,25 +129,29 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
|
||||
std::cerr << "GetModuleFileName failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
WCHAR *p = cmd + wcslen(cmd);
|
||||
while (p > cmd && *p != L'\\') p--;
|
||||
*(p+1) = 0;
|
||||
WCHAR* p = cmd + wcslen(cmd);
|
||||
while (p > cmd && *p != L'\\')
|
||||
p--;
|
||||
*(p + 1) = 0;
|
||||
wcscat(cmd, cmdConsoleBufChild);
|
||||
wcscat(cmd, L".exe");
|
||||
|
||||
bool success = CreateProcessW(NULL, // No module name (use command line)
|
||||
cmd, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
bInheritHandles, // Set handle inheritance
|
||||
dwCreationFlags,
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&startupInfo, // Pointer to STARTUPINFO structure
|
||||
&processInfo) != 0; // Pointer to PROCESS_INFORMATION structure
|
||||
bool success =
|
||||
CreateProcessW(NULL, // No module name (use command line)
|
||||
cmd, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
bInheritHandles, // Set handle inheritance
|
||||
dwCreationFlags,
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&startupInfo, // Pointer to STARTUPINFO structure
|
||||
&processInfo) !=
|
||||
0; // Pointer to PROCESS_INFORMATION structure
|
||||
if (!success) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" << std::endl;
|
||||
std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")"
|
||||
<< std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
return success;
|
||||
@@ -157,8 +161,8 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
|
||||
static void finishProcess(bool success)
|
||||
{
|
||||
if (success) {
|
||||
success = WaitForSingleObject(processInfo.hProcess, waitTimeout)
|
||||
== WAIT_OBJECT_0;
|
||||
success =
|
||||
WaitForSingleObject(processInfo.hProcess, waitTimeout) == WAIT_OBJECT_0;
|
||||
};
|
||||
if (!success) {
|
||||
TerminateProcess(processInfo.hProcess, 1);
|
||||
@@ -174,8 +178,8 @@ static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
|
||||
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
securityAttributes.bInheritHandle = TRUE;
|
||||
securityAttributes.lpSecurityDescriptor = NULL;
|
||||
return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0
|
||||
? false : true;
|
||||
return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false
|
||||
: true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -197,16 +201,17 @@ static HANDLE createFile(LPCWSTR fileName)
|
||||
securityAttributes.bInheritHandle = TRUE;
|
||||
securityAttributes.lpSecurityDescriptor = NULL;
|
||||
|
||||
HANDLE file = CreateFileW(fileName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, // do not share
|
||||
&securityAttributes,
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL); // no template
|
||||
HANDLE file =
|
||||
CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE,
|
||||
0, // do not share
|
||||
&securityAttributes,
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL); // no template
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" << std::endl;
|
||||
std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")"
|
||||
<< std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
return file;
|
||||
@@ -223,7 +228,7 @@ static void finishFile(HANDLE file)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef MAPVK_VK_TO_VSC
|
||||
# define MAPVK_VK_TO_VSC (0)
|
||||
#define MAPVK_VK_TO_VSC (0)
|
||||
#endif
|
||||
|
||||
static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
|
||||
@@ -238,9 +243,8 @@ static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
|
||||
keyCode = 'K';
|
||||
}
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode);
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualScanCode =
|
||||
MapVirtualKey(inputBuffer[0].Event.KeyEvent.wVirtualKeyCode,
|
||||
MAPVK_VK_TO_VSC);
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC);
|
||||
inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr;
|
||||
inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0;
|
||||
if ((HIBYTE(keyCode) & 1) == 1) {
|
||||
@@ -255,12 +259,12 @@ static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
|
||||
inputBuffer[1].EventType = inputBuffer[0].EventType;
|
||||
inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE;
|
||||
inputBuffer[1].Event.KeyEvent.wRepeatCount = 1;
|
||||
inputBuffer[1].Event.KeyEvent.wVirtualKeyCode = inputBuffer[0].Event.
|
||||
KeyEvent.wVirtualKeyCode;
|
||||
inputBuffer[1].Event.KeyEvent.wVirtualScanCode = inputBuffer[0].Event.
|
||||
KeyEvent.wVirtualScanCode;
|
||||
inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar = inputBuffer[0].Event.
|
||||
KeyEvent.uChar.UnicodeChar;
|
||||
inputBuffer[1].Event.KeyEvent.wVirtualKeyCode =
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualKeyCode;
|
||||
inputBuffer[1].Event.KeyEvent.wVirtualScanCode =
|
||||
inputBuffer[0].Event.KeyEvent.wVirtualScanCode;
|
||||
inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar =
|
||||
inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar;
|
||||
inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0;
|
||||
}
|
||||
|
||||
@@ -292,29 +296,33 @@ static int testPipe()
|
||||
|
||||
DWORD bytesWritten = 0;
|
||||
if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
|
||||
(DWORD)encodedInputTestString.size(), &bytesWritten, NULL)
|
||||
|| bytesWritten == 0) {
|
||||
(DWORD)encodedInputTestString.size(), &bytesWritten,
|
||||
NULL) ||
|
||||
bytesWritten == 0) {
|
||||
throw std::runtime_error("WriteFile failed!");
|
||||
}
|
||||
|
||||
if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) {
|
||||
try {
|
||||
DWORD status;
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
|
||||
WAIT_OBJECT_0) {
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x"
|
||||
<< status << std::endl;
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
throw std::runtime_error("WaitForSingleObject failed!");
|
||||
}
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL)
|
||||
|| bytesRead == 0) {
|
||||
if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) ||
|
||||
bytesRead == 0) {
|
||||
throw std::runtime_error("ReadFile#1 failed!");
|
||||
}
|
||||
if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size()
|
||||
&& !ReadFile(outPipeRead, buffer + bytesRead,
|
||||
sizeof(buffer) - bytesRead, &bytesRead, NULL))
|
||||
|| bytesRead == 0) {
|
||||
if ((bytesRead <
|
||||
encodedTestString.size() + 1 + encodedInputTestString.size() &&
|
||||
!ReadFile(outPipeRead, buffer + bytesRead,
|
||||
sizeof(buffer) - bytesRead, &bytesRead, NULL)) ||
|
||||
bytesRead == 0) {
|
||||
throw std::runtime_error("ReadFile#2 failed!");
|
||||
}
|
||||
if (memcmp(buffer, encodedTestString.c_str(),
|
||||
@@ -323,31 +331,37 @@ static int testPipe()
|
||||
encodedInputTestString.c_str(),
|
||||
encodedInputTestString.size()) == 0) {
|
||||
bytesRead = 0;
|
||||
if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, NULL)
|
||||
|| bytesRead == 0) {
|
||||
if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead,
|
||||
NULL) ||
|
||||
bytesRead == 0) {
|
||||
throw std::runtime_error("ReadFile#3 failed!");
|
||||
}
|
||||
buffer2[bytesRead - 1] = 0;
|
||||
didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
|
||||
}
|
||||
if (didFail != 0) {
|
||||
std::cerr << "Pipe's output didn't match expected output!" << std::endl;
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
|
||||
dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size());
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
|
||||
std::cerr << "Pipe's output didn't match expected output!"
|
||||
<< std::endl;
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer,
|
||||
encodedTestString.size());
|
||||
dumpBuffers<char>(encodedInputTestString.c_str(),
|
||||
buffer + encodedTestString.size() + 1,
|
||||
encodedInputTestString.size());
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer2,
|
||||
encodedTestString.size());
|
||||
}
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "In function testPipe, line " << __LINE__ << ": "
|
||||
std::cerr << "In function testPipe, line " << __LINE__ << ": "
|
||||
<< ex.what() << std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
finishProcess(didFail == 0);
|
||||
}
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "In function testPipe, line " << __LINE__ << ": "
|
||||
<< ex.what() << std::endl;
|
||||
std::cerr << "In function testPipe, line " << __LINE__ << ": " << ex.what()
|
||||
<< std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
finishPipe(inPipeRead, inPipeWrite);
|
||||
@@ -375,14 +389,14 @@ static int testFile()
|
||||
char buffer2[200];
|
||||
|
||||
int length;
|
||||
if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
|
||||
buffer, sizeof(buffer),
|
||||
NULL, NULL)) == 0) {
|
||||
if ((length =
|
||||
WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
|
||||
buffer, sizeof(buffer), NULL, NULL)) == 0) {
|
||||
throw std::runtime_error("WideCharToMultiByte failed!");
|
||||
}
|
||||
buffer[length - 1] = '\n';
|
||||
if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL)
|
||||
|| bytesWritten == 0) {
|
||||
if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL) ||
|
||||
bytesWritten == 0) {
|
||||
throw std::runtime_error("WriteFile failed!");
|
||||
}
|
||||
if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
||||
@@ -393,18 +407,20 @@ static int testFile()
|
||||
DWORD bytesRead = 0;
|
||||
try {
|
||||
DWORD status;
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
|
||||
WAIT_OBJECT_0) {
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x"
|
||||
<< status << std::endl;
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
throw std::runtime_error("WaitForSingleObject failed!");
|
||||
}
|
||||
if (SetFilePointer(outFile, 0, 0, FILE_BEGIN)
|
||||
== INVALID_SET_FILE_POINTER) {
|
||||
if (SetFilePointer(outFile, 0, 0, FILE_BEGIN) ==
|
||||
INVALID_SET_FILE_POINTER) {
|
||||
throw std::runtime_error("SetFilePointer#1 failed!");
|
||||
}
|
||||
if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL)
|
||||
|| bytesRead == 0) {
|
||||
if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) ||
|
||||
bytesRead == 0) {
|
||||
throw std::runtime_error("ReadFile#1 failed!");
|
||||
}
|
||||
buffer[bytesRead - 1] = 0;
|
||||
@@ -414,35 +430,40 @@ static int testFile()
|
||||
encodedInputTestString.c_str(),
|
||||
encodedInputTestString.size() - 1) == 0) {
|
||||
bytesRead = 0;
|
||||
if (SetFilePointer(errFile, 0, 0, FILE_BEGIN)
|
||||
== INVALID_SET_FILE_POINTER) {
|
||||
if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) ==
|
||||
INVALID_SET_FILE_POINTER) {
|
||||
throw std::runtime_error("SetFilePointer#2 failed!");
|
||||
}
|
||||
if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL)
|
||||
|| bytesRead == 0) {
|
||||
if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL) ||
|
||||
bytesRead == 0) {
|
||||
throw std::runtime_error("ReadFile#2 failed!");
|
||||
}
|
||||
buffer2[bytesRead - 1] = 0;
|
||||
didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
|
||||
}
|
||||
if (didFail != 0) {
|
||||
std::cerr << "File's output didn't match expected output!" << std::endl;
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
|
||||
dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size() - 1);
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
|
||||
std::cerr << "File's output didn't match expected output!"
|
||||
<< std::endl;
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer,
|
||||
encodedTestString.size());
|
||||
dumpBuffers<char>(encodedInputTestString.c_str(),
|
||||
buffer + encodedTestString.size() + 1,
|
||||
encodedInputTestString.size() - 1);
|
||||
dumpBuffers<char>(encodedTestString.c_str(), buffer2,
|
||||
encodedTestString.size());
|
||||
}
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "In function testFile, line " << __LINE__ << ": "
|
||||
std::cerr << "In function testFile, line " << __LINE__ << ": "
|
||||
<< ex.what() << std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
finishProcess(didFail == 0);
|
||||
}
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "In function testFile, line " << __LINE__ << ": "
|
||||
<< ex.what() << std::endl;
|
||||
std::cerr << "In function testFile, line " << __LINE__ << ": " << ex.what()
|
||||
<< std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
finishFile(inFile);
|
||||
@@ -452,7 +473,7 @@ static int testFile()
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WINNT_VISTA
|
||||
# define _WIN32_WINNT_VISTA 0x0600
|
||||
#define _WIN32_WINNT_VISTA 0x0600
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -478,16 +499,17 @@ static int testConsole()
|
||||
DWORD FontFamily = TestFontFamily;
|
||||
DWORD FontSize = TestFontSize;
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
|
||||
# pragma warning (push)
|
||||
# ifdef __INTEL_COMPILER
|
||||
# pragma warning (disable:1478)
|
||||
# else
|
||||
# pragma warning (disable:4996)
|
||||
# endif
|
||||
#pragma warning(push)
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning(disable : 1478)
|
||||
#else
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
const bool isVistaOrGreater = LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
|
||||
#endif
|
||||
const bool isVistaOrGreater =
|
||||
LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
|
||||
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
|
||||
# pragma warning (pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
if (!isVistaOrGreater) {
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
|
||||
@@ -502,11 +524,12 @@ static int testConsole()
|
||||
(LPBYTE)&FontSize, &dwordSize);
|
||||
|
||||
RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
|
||||
(BYTE *)&TestFontFamily, sizeof(TestFontFamily));
|
||||
(BYTE*)&TestFontFamily, sizeof(TestFontFamily));
|
||||
RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
|
||||
(BYTE *)TestFaceName, (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
|
||||
(BYTE*)TestFaceName,
|
||||
(DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
|
||||
RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
|
||||
(BYTE *)&TestFontSize, sizeof(TestFontSize));
|
||||
(BYTE*)&TestFontSize, sizeof(TestFontSize));
|
||||
|
||||
restoreConsole = true;
|
||||
forceNewConsole = true;
|
||||
@@ -516,7 +539,8 @@ static int testConsole()
|
||||
}
|
||||
RegCloseKey(hConsoleKey);
|
||||
} else {
|
||||
std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl;
|
||||
std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
|
||||
@@ -530,15 +554,17 @@ static int testConsole()
|
||||
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
securityAttributes.bInheritHandle = TRUE;
|
||||
securityAttributes.lpSecurityDescriptor = NULL;
|
||||
hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
&securityAttributes, OPEN_EXISTING, 0, NULL);
|
||||
hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (hIn == INVALID_HANDLE_VALUE) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "CreateFile(CONIN$)" << std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
&securityAttributes, OPEN_EXISTING, 0, NULL);
|
||||
hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (hOut == INVALID_HANDLE_VALUE) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "CreateFile(CONOUT$)" << std::endl;
|
||||
@@ -556,10 +582,18 @@ static int testConsole()
|
||||
memset(&consoleFont, 0, sizeof(consoleFont));
|
||||
consoleFont.cbSize = sizeof(consoleFont);
|
||||
HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
|
||||
typedef BOOL (WINAPI *GetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
|
||||
typedef BOOL (WINAPI *SetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
|
||||
GetCurrentConsoleFontExFunc getConsoleFont = (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "GetCurrentConsoleFontEx");
|
||||
SetCurrentConsoleFontExFunc setConsoleFont = (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "SetCurrentConsoleFontEx");
|
||||
typedef BOOL(WINAPI * GetCurrentConsoleFontExFunc)(
|
||||
HANDLE hConsoleOutput, BOOL bMaximumWindow,
|
||||
PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
|
||||
typedef BOOL(WINAPI * SetCurrentConsoleFontExFunc)(
|
||||
HANDLE hConsoleOutput, BOOL bMaximumWindow,
|
||||
PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
|
||||
GetCurrentConsoleFontExFunc getConsoleFont =
|
||||
(GetCurrentConsoleFontExFunc)GetProcAddress(kernel32,
|
||||
"GetCurrentConsoleFontEx");
|
||||
SetCurrentConsoleFontExFunc setConsoleFont =
|
||||
(SetCurrentConsoleFontExFunc)GetProcAddress(kernel32,
|
||||
"SetCurrentConsoleFontEx");
|
||||
if (getConsoleFont(hOut, FALSE, &consoleFont)) {
|
||||
if (consoleFont.FontFamily != TestFontFamily) {
|
||||
consoleFont.FontFamily = TestFontFamily;
|
||||
@@ -573,18 +607,19 @@ static int testConsole()
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if (restoreConsole && RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0,
|
||||
KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) {
|
||||
if (restoreConsole &&
|
||||
RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_WRITE,
|
||||
&hConsoleKey) == ERROR_SUCCESS) {
|
||||
RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
|
||||
(BYTE *)&FontFamily, sizeof(FontFamily));
|
||||
(BYTE*)&FontFamily, sizeof(FontFamily));
|
||||
if (FaceName[0] != 0) {
|
||||
RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
|
||||
(BYTE *)FaceName, FaceNameSize);
|
||||
RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, (BYTE*)FaceName,
|
||||
FaceNameSize);
|
||||
} else {
|
||||
RegDeleteValueW(hConsoleKey, L"FaceName");
|
||||
}
|
||||
RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
|
||||
(BYTE *)&FontSize, sizeof(FontSize));
|
||||
RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD, (BYTE*)&FontSize,
|
||||
sizeof(FontSize));
|
||||
RegCloseKey(hConsoleKey);
|
||||
}
|
||||
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
@@ -594,32 +629,41 @@ static int testConsole()
|
||||
if (createProcess(NULL, NULL, NULL)) {
|
||||
try {
|
||||
DWORD status;
|
||||
if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != WAIT_OBJECT_0) {
|
||||
if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) !=
|
||||
WAIT_OBJECT_0) {
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x"
|
||||
<< status << std::endl;
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
throw std::runtime_error("WaitForSingleObject#1 failed!");
|
||||
}
|
||||
INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) /
|
||||
sizeof(UnicodeInputTestString[0])) * 2];
|
||||
sizeof(UnicodeInputTestString[0])) *
|
||||
2];
|
||||
memset(&inputBuffer, 0, sizeof(inputBuffer));
|
||||
unsigned int i;
|
||||
for (i = 0; i < (sizeof(UnicodeInputTestString) /
|
||||
sizeof(UnicodeInputTestString[0]) - 1); i++) {
|
||||
writeInputKeyEvent(&inputBuffer[i*2], UnicodeInputTestString[i]);
|
||||
sizeof(UnicodeInputTestString[0]) -
|
||||
1);
|
||||
i++) {
|
||||
writeInputKeyEvent(&inputBuffer[i * 2], UnicodeInputTestString[i]);
|
||||
}
|
||||
writeInputKeyEvent(&inputBuffer[i*2], VK_RETURN);
|
||||
writeInputKeyEvent(&inputBuffer[i * 2], VK_RETURN);
|
||||
DWORD eventsWritten = 0;
|
||||
// We need to wait a bit before writing to console so child process have started waiting for input on stdin.
|
||||
// We need to wait a bit before writing to console so child process have
|
||||
// started waiting for input on stdin.
|
||||
Sleep(300);
|
||||
if (!WriteConsoleInputW(hIn, inputBuffer, sizeof(inputBuffer) /
|
||||
sizeof(inputBuffer[0]),
|
||||
&eventsWritten) || eventsWritten == 0) {
|
||||
if (!WriteConsoleInputW(hIn, inputBuffer,
|
||||
sizeof(inputBuffer) / sizeof(inputBuffer[0]),
|
||||
&eventsWritten) ||
|
||||
eventsWritten == 0) {
|
||||
throw std::runtime_error("WriteConsoleInput failed!");
|
||||
}
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
|
||||
if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
|
||||
WAIT_OBJECT_0) {
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
|
||||
std::cerr << "WaitForSingleObject returned unexpected status 0x"
|
||||
<< status << std::endl;
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
throw std::runtime_error("WaitForSingleObject#2 failed!");
|
||||
}
|
||||
@@ -632,38 +676,48 @@ static int testConsole()
|
||||
DWORD charsRead = 0;
|
||||
coord.X = 0;
|
||||
coord.Y = screenBufferInfo.dwCursorPosition.Y - 4;
|
||||
WCHAR *outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
|
||||
WCHAR* outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
|
||||
if (!ReadConsoleOutputCharacterW(hOut, outputBuffer,
|
||||
screenBufferInfo.dwSize.X * 4, coord, &charsRead)
|
||||
|| charsRead == 0) {
|
||||
screenBufferInfo.dwSize.X * 4, coord,
|
||||
&charsRead) ||
|
||||
charsRead == 0) {
|
||||
delete[] outputBuffer;
|
||||
throw std::runtime_error("ReadConsoleOutputCharacter failed!");
|
||||
}
|
||||
std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
|
||||
std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString);
|
||||
std::wstring wideInputTestString =
|
||||
kwsys::Encoding::ToWide(encodedInputTestString);
|
||||
if (memcmp(outputBuffer, wideTestString.c_str(),
|
||||
wideTestString.size() * sizeof(wchar_t)) == 0 &&
|
||||
memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1,
|
||||
wideTestString.c_str(), wideTestString.size() * sizeof(wchar_t)) == 0 &&
|
||||
wideTestString.c_str(),
|
||||
wideTestString.size() * sizeof(wchar_t)) == 0 &&
|
||||
memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2,
|
||||
UnicodeInputTestString, sizeof(UnicodeInputTestString) -
|
||||
sizeof(WCHAR)) == 0 &&
|
||||
UnicodeInputTestString,
|
||||
sizeof(UnicodeInputTestString) - sizeof(WCHAR)) == 0 &&
|
||||
memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3,
|
||||
wideInputTestString.c_str(),
|
||||
(wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0
|
||||
) {
|
||||
(wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0) {
|
||||
didFail = 0;
|
||||
} else {
|
||||
std::cerr << "Console's output didn't match expected output!" << std::endl;
|
||||
dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, wideTestString.size());
|
||||
dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 1, wideTestString.size());
|
||||
dumpBuffers<wchar_t>(UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
|
||||
dumpBuffers<wchar_t>(wideInputTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 3, wideInputTestString.size() - 1);
|
||||
std::cerr << "Console's output didn't match expected output!"
|
||||
<< std::endl;
|
||||
dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer,
|
||||
wideTestString.size());
|
||||
dumpBuffers<wchar_t>(wideTestString.c_str(),
|
||||
outputBuffer + screenBufferInfo.dwSize.X * 1,
|
||||
wideTestString.size());
|
||||
dumpBuffers<wchar_t>(
|
||||
UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2,
|
||||
(sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
|
||||
dumpBuffers<wchar_t>(wideInputTestString.c_str(),
|
||||
outputBuffer + screenBufferInfo.dwSize.X * 3,
|
||||
wideInputTestString.size() - 1);
|
||||
}
|
||||
delete[] outputBuffer;
|
||||
} catch (const std::runtime_error &ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
DWORD lastError = GetLastError();
|
||||
std::cerr << "In function testConsole, line " << __LINE__ << ": "
|
||||
std::cerr << "In function testConsole, line " << __LINE__ << ": "
|
||||
<< ex.what() << std::endl;
|
||||
displayError(lastError);
|
||||
}
|
||||
@@ -683,15 +737,15 @@ static int testConsole()
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int testConsoleBuf(int, char*[])
|
||||
int testConsoleBuf(int, char* [])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#if defined(_WIN32)
|
||||
beforeInputEvent = CreateEventW(NULL,
|
||||
FALSE, // auto-reset event
|
||||
FALSE, // initial state is nonsignaled
|
||||
BeforeInputEventName); // object name
|
||||
FALSE, // auto-reset event
|
||||
FALSE, // initial state is nonsignaled
|
||||
BeforeInputEventName); // object name
|
||||
if (!beforeInputEvent) {
|
||||
std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl;
|
||||
return 1;
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef testConsoleBuf_hxx
|
||||
#define testConsoleBuf_hxx
|
||||
|
||||
@@ -18,8 +9,9 @@ static const wchar_t BeforeInputEventName[] = L"BeforeInputEvent";
|
||||
static const wchar_t AfterOutputEventName[] = L"AfterOutputEvent";
|
||||
|
||||
// यूनिकोड είναι здорово!
|
||||
static const wchar_t UnicodeTestString[] = L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
|
||||
L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
|
||||
L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
|
||||
static const wchar_t UnicodeTestString[] =
|
||||
L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
|
||||
L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
|
||||
L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
|
||||
|
||||
#endif
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(ConsoleBuf.hxx)
|
||||
@@ -17,11 +8,12 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "ConsoleBuf.hxx.in"
|
||||
# include "Encoding.hxx.in"
|
||||
#include "ConsoleBuf.hxx.in"
|
||||
#include "Encoding.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "testConsoleBuf.hxx"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(DynamicLoader.hxx)
|
||||
|
||||
#if defined(__BEOS__) || defined(__HAIKU__)
|
||||
#include <be/kernel/OS.h> /* disable_debugger() API. */
|
||||
#include <be/kernel/OS.h> /* disable_debugger() API. */
|
||||
#endif
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "DynamicLoader.hxx.in"
|
||||
#include "DynamicLoader.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Include with <> instead of "" to avoid getting any in-source copy
|
||||
// left on disk.
|
||||
@@ -53,41 +44,36 @@ static std::string GetLibName(const char* lname)
|
||||
* r2: should GetSymbolAddress succeed ?
|
||||
* r3: should CloseLibrary succeed ?
|
||||
*/
|
||||
static int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
|
||||
static int TestDynamicLoader(const char* libname, const char* symbol, int r1,
|
||||
int r2, int r3)
|
||||
{
|
||||
std::cerr << "Testing: " << libname << std::endl;
|
||||
kwsys::DynamicLoader::LibraryHandle l
|
||||
= kwsys::DynamicLoader::OpenLibrary(libname);
|
||||
kwsys::DynamicLoader::LibraryHandle l =
|
||||
kwsys::DynamicLoader::OpenLibrary(libname);
|
||||
// If result is incompatible with expectation just fails (xor):
|
||||
if( (r1 && !l) || (!r1 && l) )
|
||||
{
|
||||
std::cerr
|
||||
<< kwsys::DynamicLoader::LastError() << std::endl;
|
||||
if ((r1 && !l) || (!r1 && l)) {
|
||||
std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
kwsys::DynamicLoader::SymbolPointer f
|
||||
= kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
|
||||
if( (r2 && !f) || (!r2 && f) )
|
||||
{
|
||||
std::cerr
|
||||
<< kwsys::DynamicLoader::LastError() << std::endl;
|
||||
}
|
||||
kwsys::DynamicLoader::SymbolPointer f =
|
||||
kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
|
||||
if ((r2 && !f) || (!r2 && f)) {
|
||||
std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#ifndef __APPLE__
|
||||
int s = kwsys::DynamicLoader::CloseLibrary(l);
|
||||
if( (r3 && !s) || (!r3 && s) )
|
||||
{
|
||||
std::cerr
|
||||
<< kwsys::DynamicLoader::LastError() << std::endl;
|
||||
if ((r3 && !s) || (!r3 && s)) {
|
||||
std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)r3;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDynamicLoader(int argc, char *argv[])
|
||||
int testDynamicLoader(int argc, char* argv[])
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||
@@ -95,34 +81,37 @@ int testDynamicLoader(int argc, char *argv[])
|
||||
disable_debugger(1);
|
||||
#endif
|
||||
int res = 0;
|
||||
if( argc == 3 )
|
||||
{
|
||||
if (argc == 3) {
|
||||
// User specify a libname and symbol to check.
|
||||
res = TestDynamicLoader(argv[1], argv[2],1,1,1);
|
||||
res = TestDynamicLoader(argv[1], argv[2], 1, 1, 1);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// dlopen() on Syllable before 11/22/2007 doesn't return 0 on error
|
||||
#ifndef __SYLLABLE__
|
||||
// Make sure that inexistent lib is giving correct result
|
||||
res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
|
||||
res += TestDynamicLoader("azerty_", "foo_bar", 0, 0, 0);
|
||||
// Make sure that random binary file cannot be assimilated as dylib
|
||||
res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin", "wp",0,0,0);
|
||||
res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin",
|
||||
"wp", 0, 0, 0);
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
// This one is actually fun to test, since dlopen is by default loaded...wonder why :)
|
||||
res += TestDynamicLoader("foobar.lib", "dlopen",0,1,0);
|
||||
res += TestDynamicLoader("libdl.so", "dlopen",1,1,1);
|
||||
res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
|
||||
// This one is actually fun to test, since dlopen is by default
|
||||
// loaded...wonder why :)
|
||||
res += TestDynamicLoader("foobar.lib", "dlopen", 0, 1, 0);
|
||||
res += TestDynamicLoader("libdl.so", "dlopen", 1, 1, 1);
|
||||
res += TestDynamicLoader("libdl.so", "TestDynamicLoader", 1, 0, 1);
|
||||
#endif
|
||||
// Now try on the generated library
|
||||
std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
|
||||
res += TestDynamicLoader(libname.c_str(), "dummy",1,0,1);
|
||||
res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",1,1,1);
|
||||
res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",1,0,1);
|
||||
res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData",1,1,1);
|
||||
res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData",1,0,1);
|
||||
res += TestDynamicLoader(libname.c_str(), "dummy", 1, 0, 1);
|
||||
res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",
|
||||
1, 1, 1);
|
||||
res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",
|
||||
1, 0, 1);
|
||||
res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData", 1, 1, 1);
|
||||
res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData", 1, 0, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,16 +1,7 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifdef _WIN32
|
||||
#define DL_EXPORT __declspec( dllexport )
|
||||
#define DL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DL_EXPORT
|
||||
#endif
|
||||
|
||||
+11
-20
@@ -1,29 +1,20 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(MD5.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "MD5.h.in"
|
||||
#include "MD5.h.in"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const unsigned char testMD5input1[] =
|
||||
" A quick brown fox jumps over the lazy dog.\n"
|
||||
" This is sample text for MD5 sum input.\n";
|
||||
" A quick brown fox jumps over the lazy dog.\n"
|
||||
" This is sample text for MD5 sum input.\n";
|
||||
static const char testMD5output1[] = "8f146af46ed4f267921bb937d4d3500c";
|
||||
|
||||
static const int testMD5input2len = 28;
|
||||
@@ -40,7 +31,7 @@ static int testMD5_1(kwsysMD5* md5)
|
||||
printf("md5sum 1: expected [%s]\n"
|
||||
" got [%s]\n",
|
||||
testMD5output1, md5out);
|
||||
return (strcmp(md5out, testMD5output1) != 0)? 1:0;
|
||||
return (strcmp(md5out, testMD5output1) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int testMD5_2(kwsysMD5* md5)
|
||||
@@ -55,7 +46,7 @@ static int testMD5_2(kwsysMD5* md5)
|
||||
printf("md5sum 2: expected [%s]\n"
|
||||
" got [%s]\n",
|
||||
testMD5output2, md5out);
|
||||
return (strcmp(md5out, testMD5output2) != 0)? 1:0;
|
||||
return (strcmp(md5out, testMD5output2) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int testEncode(int argc, char* argv[])
|
||||
@@ -66,10 +57,10 @@ int testEncode(int argc, char* argv[])
|
||||
|
||||
/* Test MD5 digest. */
|
||||
{
|
||||
kwsysMD5* md5 = kwsysMD5_New();
|
||||
result |= testMD5_1(md5);
|
||||
result |= testMD5_2(md5);
|
||||
kwsysMD5_Delete(md5);
|
||||
kwsysMD5* md5 = kwsysMD5_New();
|
||||
result |= testMD5_1(md5);
|
||||
result |= testMD5_2(md5);
|
||||
kwsysMD5_Delete(md5);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#include KWSYS_HEADER(Encoding.hxx)
|
||||
@@ -20,68 +11,63 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Encoding.hxx.in"
|
||||
# include "Encoding.h.in"
|
||||
#include "Encoding.h.in"
|
||||
#include "Encoding.hxx.in"
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const unsigned char helloWorldStrings[][32] =
|
||||
{
|
||||
static const unsigned char helloWorldStrings[][32] = {
|
||||
// English
|
||||
{'H','e','l','l','o',' ','W','o','r','l','d',0},
|
||||
{ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 },
|
||||
// Japanese
|
||||
{0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3,
|
||||
0x81, 0xA1, 0xE3, 0x81, 0xAF, 0xE4, 0xB8, 0x96, 0xE7, 0x95,
|
||||
0x8C, 0},
|
||||
// Arabic
|
||||
{0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7,
|
||||
0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD8, 0xB9, 0xD8, 0xA7, 0xD9,
|
||||
0x84, 0xD9, 0x85, 0},
|
||||
{ 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3, 0x81,
|
||||
0xA1, 0xE3, 0x81, 0xAF, 0xE4, 0xB8, 0x96, 0xE7, 0x95, 0x8C, 0 },
|
||||
// Arabic
|
||||
{ 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7, 0x20, 0xD8,
|
||||
0xA7, 0xD9, 0x84, 0xD8, 0xB9, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x85, 0 },
|
||||
// Yiddish
|
||||
{0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x90, 0x20, 0xD7,
|
||||
0x95, 0xD7, 0x95, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98, 0},
|
||||
{ 0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x90, 0x20, 0xD7,
|
||||
0x95, 0xD7, 0x95, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98, 0 },
|
||||
// Russian
|
||||
{0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5,
|
||||
0xD1, 0x82, 0x20, 0xD0, 0xBC, 0xD0, 0xB8, 0xD1, 0x80, 0},
|
||||
{ 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5,
|
||||
0xD1, 0x82, 0x20, 0xD0, 0xBC, 0xD0, 0xB8, 0xD1, 0x80, 0 },
|
||||
// Latin
|
||||
{0x4D, 0x75, 0x6E, 0x64, 0x75, 0x73, 0x20, 0x73, 0x61, 0x6C,
|
||||
0x76, 0x65, 0},
|
||||
{ 0x4D, 0x75, 0x6E, 0x64, 0x75, 0x73, 0x20, 0x73, 0x61, 0x6C, 0x76, 0x65,
|
||||
0 },
|
||||
// Swahili
|
||||
{0x68, 0x75, 0x6A, 0x61, 0x6D, 0x62, 0x6F, 0x20, 0x44, 0x75,
|
||||
0x6E, 0x69, 0x61, 0},
|
||||
{ 0x68, 0x75, 0x6A, 0x61, 0x6D, 0x62, 0x6F, 0x20, 0x44, 0x75, 0x6E, 0x69,
|
||||
0x61, 0 },
|
||||
// Icelandic
|
||||
{0x48, 0x61, 0x6C, 0x6C, 0xC3, 0xB3, 0x20, 0x68, 0x65, 0x69,
|
||||
0x6D, 0x75, 0x72, 0},
|
||||
{0}
|
||||
{ 0x48, 0x61, 0x6C, 0x6C, 0xC3, 0xB3, 0x20, 0x68, 0x65, 0x69, 0x6D, 0x75,
|
||||
0x72, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int testHelloWorldEncoding()
|
||||
{
|
||||
int ret = 0;
|
||||
for(int i=0; helloWorldStrings[i][0] != 0; i++)
|
||||
{
|
||||
for (int i = 0; helloWorldStrings[i][0] != 0; i++) {
|
||||
std::string str = reinterpret_cast<const char*>(helloWorldStrings[i]);
|
||||
std::cout << str << std::endl;
|
||||
std::wstring wstr = kwsys::Encoding::ToWide(str);
|
||||
std::string str2 = kwsys::Encoding::ToNarrow(wstr);
|
||||
wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str());
|
||||
char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr);
|
||||
if(!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str())))
|
||||
{
|
||||
if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()))) {
|
||||
std::cout << "converted string was different: " << str2 << std::endl;
|
||||
std::cout << "converted string was different: " << c_str2 << std::endl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
free(c_wstr);
|
||||
free(c_str2);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -91,55 +77,49 @@ static int testRobustEncoding()
|
||||
// unicode correctly/gracefully
|
||||
|
||||
int ret = 0;
|
||||
char cstr[] = {(char)-1, 0};
|
||||
char cstr[] = { (char)-1, 0 };
|
||||
// this conversion could fail
|
||||
std::wstring wstr = kwsys::Encoding::ToWide(cstr);
|
||||
|
||||
wstr = kwsys::Encoding::ToWide(NULL);
|
||||
if(wstr != L"")
|
||||
{
|
||||
if (wstr != L"") {
|
||||
const wchar_t* wcstr = wstr.c_str();
|
||||
std::cout << "ToWide(NULL) returned";
|
||||
for(size_t i=0; i<wstr.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); i++) {
|
||||
std::cout << " " << std::hex << (int)wcstr[i];
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
wstr = kwsys::Encoding::ToWide("");
|
||||
if(wstr != L"")
|
||||
{
|
||||
if (wstr != L"") {
|
||||
const wchar_t* wcstr = wstr.c_str();
|
||||
std::cout << "ToWide(\"\") returned";
|
||||
for(size_t i=0; i<wstr.size(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); i++) {
|
||||
std::cout << " " << std::hex << (int)wcstr[i];
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// 16 bit wchar_t - we make an invalid surrogate pair
|
||||
wchar_t cwstr[] = {0xD801, 0xDA00, 0};
|
||||
wchar_t cwstr[] = { 0xD801, 0xDA00, 0 };
|
||||
// this conversion could fail
|
||||
std::string win_str = kwsys::Encoding::ToNarrow(cwstr);
|
||||
#endif
|
||||
|
||||
std::string str = kwsys::Encoding::ToNarrow(NULL);
|
||||
if(str != "")
|
||||
{
|
||||
if (str != "") {
|
||||
std::cout << "ToNarrow(NULL) returned " << str << std::endl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
str = kwsys::Encoding::ToNarrow(L"");
|
||||
if(wstr != L"")
|
||||
{
|
||||
if (wstr != L"") {
|
||||
std::cout << "ToNarrow(\"\") returned " << str << std::endl;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -148,23 +128,18 @@ static int testCommandLineArguments()
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
char const* argv[2] = {
|
||||
"./app.exe",
|
||||
(char const*)helloWorldStrings[1]
|
||||
};
|
||||
char const* argv[2] = { "./app.exe", (char const*)helloWorldStrings[1] };
|
||||
|
||||
kwsys::Encoding::CommandLineArguments args(2, argv);
|
||||
kwsys::Encoding::CommandLineArguments arg2 =
|
||||
kwsys::Encoding::CommandLineArguments(args);
|
||||
|
||||
char const* const* u8_argv = args.argv();
|
||||
for(int i=0; i<args.argc(); i++)
|
||||
{
|
||||
for (int i = 0; i < args.argc(); i++) {
|
||||
char const* u8_arg = u8_argv[i];
|
||||
if(strcmp(argv[i], u8_arg) != 0)
|
||||
{
|
||||
std::cout << "argv[" << i << "] " << argv[i] << " != "
|
||||
<< u8_arg << std::endl;
|
||||
if (strcmp(argv[i], u8_arg) != 0) {
|
||||
std::cout << "argv[" << i << "] " << argv[i] << " != " << u8_arg
|
||||
<< std::endl;
|
||||
status++;
|
||||
}
|
||||
}
|
||||
@@ -176,17 +151,14 @@ static int testCommandLineArguments()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int testEncoding(int, char*[])
|
||||
int testEncoding(int, char* [])
|
||||
{
|
||||
const char* loc = setlocale(LC_ALL, "");
|
||||
if(loc)
|
||||
{
|
||||
if (loc) {
|
||||
std::cout << "Locale: " << loc << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cout << "Locale: None" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#include KWSYS_HEADER(FStream.hxx)
|
||||
#include <string.h>
|
||||
#ifdef __BORLANDC__
|
||||
# include <mem.h> /* memcmp */
|
||||
#include <mem.h> /* memcmp */
|
||||
#endif
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "FStream.hxx.in"
|
||||
#include "FStream.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@@ -33,10 +24,9 @@
|
||||
static int testNoFile()
|
||||
{
|
||||
kwsys::ifstream in_file("NoSuchFile.txt");
|
||||
if(in_file)
|
||||
{
|
||||
if (in_file) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -44,90 +34,78 @@ static int testNoFile()
|
||||
static const int num_test_files = 7;
|
||||
static const int max_test_file_size = 45;
|
||||
|
||||
static kwsys::FStream::BOM expected_bom[num_test_files] =
|
||||
{
|
||||
kwsys::FStream::BOM_None,
|
||||
kwsys::FStream::BOM_None,
|
||||
kwsys::FStream::BOM_UTF8,
|
||||
kwsys::FStream::BOM_UTF16LE,
|
||||
kwsys::FStream::BOM_UTF16BE,
|
||||
kwsys::FStream::BOM_UTF32LE,
|
||||
static kwsys::FStream::BOM expected_bom[num_test_files] = {
|
||||
kwsys::FStream::BOM_None, kwsys::FStream::BOM_None,
|
||||
kwsys::FStream::BOM_UTF8, kwsys::FStream::BOM_UTF16LE,
|
||||
kwsys::FStream::BOM_UTF16BE, kwsys::FStream::BOM_UTF32LE,
|
||||
kwsys::FStream::BOM_UTF32BE
|
||||
};
|
||||
|
||||
static unsigned char expected_bom_data[num_test_files][5] =
|
||||
{
|
||||
{0},
|
||||
{0},
|
||||
{3, 0xEF, 0xBB, 0xBF},
|
||||
{2, 0xFF, 0xFE},
|
||||
{2, 0xFE, 0xFF},
|
||||
{4, 0xFF, 0xFE, 0x00, 0x00},
|
||||
{4, 0x00, 0x00, 0xFE, 0xFF},
|
||||
static unsigned char expected_bom_data[num_test_files][5] = {
|
||||
{ 0 },
|
||||
{ 0 },
|
||||
{ 3, 0xEF, 0xBB, 0xBF },
|
||||
{ 2, 0xFF, 0xFE },
|
||||
{ 2, 0xFE, 0xFF },
|
||||
{ 4, 0xFF, 0xFE, 0x00, 0x00 },
|
||||
{ 4, 0x00, 0x00, 0xFE, 0xFF },
|
||||
};
|
||||
|
||||
static unsigned char file_data[num_test_files][max_test_file_size] =
|
||||
{
|
||||
{1, 'H'},
|
||||
{11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'},
|
||||
{11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'},
|
||||
{22, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20, 0x00,
|
||||
0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00},
|
||||
{22, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20,
|
||||
0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64},
|
||||
{44, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
|
||||
0x6C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00},
|
||||
{44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C,
|
||||
0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72,
|
||||
0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64},
|
||||
static unsigned char file_data[num_test_files][max_test_file_size] = {
|
||||
{ 1, 'H' },
|
||||
{ 11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' },
|
||||
{ 11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' },
|
||||
{ 22, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20,
|
||||
0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00 },
|
||||
{ 22, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00,
|
||||
0x20, 0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64 },
|
||||
{ 44, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00,
|
||||
0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||
0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00,
|
||||
0x00, 0x6C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00 },
|
||||
{ 44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
|
||||
0x6C, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00,
|
||||
0x72, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64 },
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int testBOM()
|
||||
{
|
||||
// test various encodings in binary mode
|
||||
for(int i=0; i<num_test_files; i++)
|
||||
for (int i = 0; i < num_test_files; i++) {
|
||||
{
|
||||
{
|
||||
kwsys::ofstream out("bom.txt", kwsys::ofstream::binary);
|
||||
out.write(reinterpret_cast<const char*>(expected_bom_data[i]+1),
|
||||
out.write(reinterpret_cast<const char*>(expected_bom_data[i] + 1),
|
||||
*expected_bom_data[i]);
|
||||
out.write(reinterpret_cast<const char*>(file_data[i]+1),
|
||||
out.write(reinterpret_cast<const char*>(file_data[i] + 1),
|
||||
file_data[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
kwsys::ifstream in("bom.txt", kwsys::ofstream::binary);
|
||||
kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in);
|
||||
if(bom != expected_bom[i])
|
||||
{
|
||||
if (bom != expected_bom[i]) {
|
||||
std::cout << "Unexpected BOM " << i << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
char data[max_test_file_size];
|
||||
in.read(data, file_data[i][0]);
|
||||
if(!in.good())
|
||||
{
|
||||
if (!in.good()) {
|
||||
std::cout << "Unable to read data " << i << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(memcmp(data, file_data[i]+1, file_data[i][0]) != 0)
|
||||
{
|
||||
if (memcmp(data, file_data[i] + 1, file_data[i][0]) != 0) {
|
||||
std::cout << "Incorrect read data " << i << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int testFStream(int, char*[])
|
||||
int testFStream(int, char* [])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
||||
+10
-21
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -17,19 +8,17 @@ int testFail(int argc, char* argv[])
|
||||
{
|
||||
char* env = getenv("DASHBOARD_TEST_FROM_CTEST");
|
||||
int oldCtest = 0;
|
||||
if(env)
|
||||
{
|
||||
if(strcmp(env, "1") == 0)
|
||||
{
|
||||
if (env) {
|
||||
if (strcmp(env, "1") == 0) {
|
||||
oldCtest = 1;
|
||||
}
|
||||
}
|
||||
printf("DASHBOARD_TEST_FROM_CTEST = %s\n", env);
|
||||
}
|
||||
}
|
||||
printf("%s: This test intentionally fails\n", argv[0]);
|
||||
if(oldCtest)
|
||||
{
|
||||
printf("The version of ctest is not able to handle intentionally failing tests, so pass.\n");
|
||||
if (oldCtest) {
|
||||
printf("The version of ctest is not able to handle intentionally failing "
|
||||
"tests, so pass.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return argc;
|
||||
}
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(hash_map.hxx)
|
||||
#include KWSYS_HEADER(hash_set.hxx)
|
||||
@@ -16,18 +7,18 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "hash_map.hxx.in"
|
||||
# include "hash_set.hxx.in"
|
||||
#include "hash_map.hxx.in"
|
||||
#include "hash_set.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 1468 /* inline function cannot be explicitly instantiated */
|
||||
#pragma set woff 1468 /* inline function cannot be explicitly instantiated */
|
||||
#endif
|
||||
|
||||
template class kwsys::hash_map<const char*, int>;
|
||||
@@ -37,16 +28,15 @@ static bool test_hash_map()
|
||||
{
|
||||
typedef kwsys::hash_map<const char*, int> mtype;
|
||||
mtype m;
|
||||
const char* keys[] = {"hello", "world"};
|
||||
const char* keys[] = { "hello", "world" };
|
||||
m[keys[0]] = 1;
|
||||
m.insert(mtype::value_type(keys[1], 2));
|
||||
int sum = 0;
|
||||
for(mtype::iterator mi = m.begin(); mi != m.end(); ++mi)
|
||||
{
|
||||
for (mtype::iterator mi = m.begin(); mi != m.end(); ++mi) {
|
||||
std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
|
||||
<< std::endl;
|
||||
sum += mi->second;
|
||||
}
|
||||
}
|
||||
return sum == 3;
|
||||
}
|
||||
|
||||
@@ -57,18 +47,17 @@ static bool test_hash_set()
|
||||
s.insert(1);
|
||||
s.insert(2);
|
||||
int sum = 0;
|
||||
for(stype::iterator si = s.begin(); si != s.end(); ++si)
|
||||
{
|
||||
for (stype::iterator si = s.begin(); si != s.end(); ++si) {
|
||||
std::cout << "Found entry [" << *si << "]" << std::endl;
|
||||
sum += *si;
|
||||
}
|
||||
}
|
||||
return sum == 3;
|
||||
}
|
||||
|
||||
int testHashSTL(int, char*[])
|
||||
int testHashSTL(int, char* [])
|
||||
{
|
||||
bool result = true;
|
||||
result = test_hash_map() && result;
|
||||
result = test_hash_set() && result;
|
||||
return result? 0:1;
|
||||
return result ? 0 : 1;
|
||||
}
|
||||
+64
-89
@@ -1,163 +1,138 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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)
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <string.h> /* strlen */
|
||||
#include <vector>
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "Configure.hxx.in"
|
||||
#include "Configure.hxx.in"
|
||||
#endif
|
||||
|
||||
int testIOS(int, char*[])
|
||||
int testIOS(int, char* [])
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
const char hello[] = "hello";
|
||||
ostr << hello;
|
||||
if(ostr.str() != hello)
|
||||
{
|
||||
if (ostr.str() != hello) {
|
||||
std::cerr << "failed to write hello to ostr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
const char world[] = "world";
|
||||
std::ostringstream ostr2;
|
||||
ostr2.write( hello, strlen(hello) ); /* I could do sizeof */
|
||||
ostr2.put( '\0' );
|
||||
ostr2.write( world, strlen(world) );
|
||||
if(ostr2.str().size() != strlen(hello) + 1 + strlen(world) )
|
||||
{
|
||||
ostr2.write(hello, strlen(hello)); /* I could do sizeof */
|
||||
ostr2.put('\0');
|
||||
ostr2.write(world, strlen(world));
|
||||
if (ostr2.str().size() != strlen(hello) + 1 + strlen(world)) {
|
||||
std::cerr << "failed to write hello to ostr2" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
static const unsigned char array[] = { 0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x01,0x01,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x64,0x00,0x2c,0x00,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x49,0x54,0x4b,0x2f,0x47,0x44,0x43,0x4d,0x2f,0x4f,0x70,0x65,0x6e,0x4a,0x50,0x45,0x47,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0xff,0x90,0x00,0x0a,0x00,0x00,0x00,0x00,0x06,0x2c,0x00,0x01,0xff,0x93,0xcf,0xb0,0x18,0x08,0x7f,0xc6,0x99,0xbf,0xff,0xc0,0xf8,0xc1,0xc1,0xf3,0x05,0x81,0xf2,0x83,0x0a,0xa5,0xff,0x10,0x90,0xbf,0x2f,0xff,0x04,0xa8,0x7f,0xc0,0xf8,0xc4,0xc1,0xf3,0x09,0x81,0xf3,0x0c,0x19,0x34 };
|
||||
}
|
||||
static const unsigned char array[] = {
|
||||
0xff, 0x4f, 0xff, 0x51, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x01, 0xff, 0x52, 0x00,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, 0x04, 0x00, 0x01, 0xff,
|
||||
0x5c, 0x00, 0x13, 0x40, 0x40, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48,
|
||||
0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0xff, 0x64, 0x00, 0x2c,
|
||||
0x00, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79,
|
||||
0x20, 0x49, 0x54, 0x4b, 0x2f, 0x47, 0x44, 0x43, 0x4d, 0x2f, 0x4f, 0x70,
|
||||
0x65, 0x6e, 0x4a, 0x50, 0x45, 0x47, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0xff, 0x90, 0x00, 0x0a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x2c, 0x00, 0x01, 0xff, 0x93, 0xcf, 0xb0, 0x18, 0x08,
|
||||
0x7f, 0xc6, 0x99, 0xbf, 0xff, 0xc0, 0xf8, 0xc1, 0xc1, 0xf3, 0x05, 0x81,
|
||||
0xf2, 0x83, 0x0a, 0xa5, 0xff, 0x10, 0x90, 0xbf, 0x2f, 0xff, 0x04, 0xa8,
|
||||
0x7f, 0xc0, 0xf8, 0xc4, 0xc1, 0xf3, 0x09, 0x81, 0xf3, 0x0c, 0x19, 0x34
|
||||
};
|
||||
const size_t narray = sizeof(array); // 180
|
||||
std::stringstream strstr;
|
||||
strstr.write( (char*)array, narray );
|
||||
//strstr.seekp( narray / 2 ); // set position of put pointer in mid string
|
||||
if(strstr.str().size() != narray )
|
||||
{
|
||||
strstr.write((char*)array, narray);
|
||||
// strstr.seekp( narray / 2 ); // set position of put pointer in mid string
|
||||
if (strstr.str().size() != narray) {
|
||||
std::cerr << "failed to write array to strstr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::istringstream istr(" 10 20 str ");
|
||||
std::string s;
|
||||
int x;
|
||||
if(istr >> x)
|
||||
{
|
||||
if(x != 10)
|
||||
{
|
||||
if (istr >> x) {
|
||||
if (x != 10) {
|
||||
std::cerr << "x != 10" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read 10 from istr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if(istr >> x)
|
||||
{
|
||||
if(x != 20)
|
||||
{
|
||||
}
|
||||
if (istr >> x) {
|
||||
if (x != 20) {
|
||||
std::cerr << "x != 20" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read 20 from istr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if(istr >> s)
|
||||
{
|
||||
if(s != "str")
|
||||
{
|
||||
}
|
||||
if (istr >> s) {
|
||||
if (s != "str") {
|
||||
std::cerr << "s != \"str\"" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read str from istr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if(istr >> s)
|
||||
{
|
||||
}
|
||||
if (istr >> s) {
|
||||
std::cerr << "Able to read past end of stream" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Clear the failure.
|
||||
istr.clear(istr.rdstate() & ~std::ios::eofbit);
|
||||
istr.clear(istr.rdstate() & ~std::ios::failbit);
|
||||
}
|
||||
}
|
||||
istr.str("30");
|
||||
if(istr >> x)
|
||||
{
|
||||
if(x != 30)
|
||||
{
|
||||
if (istr >> x) {
|
||||
if (x != 30) {
|
||||
std::cerr << "x != 30" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read 30 from istr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream sstr;
|
||||
sstr << "40 str2";
|
||||
if(sstr >> x)
|
||||
{
|
||||
if(x != 40)
|
||||
{
|
||||
if (sstr >> x) {
|
||||
if (x != 40) {
|
||||
std::cerr << "x != 40" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read 40 from sstr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if(sstr >> s)
|
||||
{
|
||||
if(s != "str2")
|
||||
{
|
||||
}
|
||||
if (sstr >> s) {
|
||||
if (s != "str2") {
|
||||
std::cerr << "s != \"str2\"" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cerr << "Failed to read str2 from sstr" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Just try to compile this.
|
||||
if(x == 12345)
|
||||
{
|
||||
std::ifstream fin("/does_not_exist",
|
||||
std::ios::in | std::ios::binary);
|
||||
}
|
||||
if (x == 12345) {
|
||||
std::ifstream fin("/does_not_exist", std::ios::in | std::ios::binary);
|
||||
}
|
||||
|
||||
std::cout << "IOS tests passed" << std::endl;
|
||||
return 0;
|
||||
|
||||
+207
-251
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Process.h)
|
||||
#include KWSYS_HEADER(Encoding.h)
|
||||
@@ -16,8 +7,8 @@
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Process.h.in"
|
||||
# include "Encoding.h.in"
|
||||
#include "Encoding.h.in"
|
||||
#include "Process.h.in"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
@@ -27,21 +18,21 @@
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <signal.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
# pragma warn -8060 /* possibly incorrect assignment */
|
||||
#pragma warn - 8060 /* possibly incorrect assignment */
|
||||
#endif
|
||||
|
||||
/* Platform-specific sleep functions. */
|
||||
|
||||
#if defined(__BEOS__) && !defined(__ZETA__)
|
||||
/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
|
||||
# include <be/kernel/OS.h>
|
||||
#include <be/kernel/OS.h>
|
||||
static inline void testProcess_usleep(unsigned int usec)
|
||||
{
|
||||
snooze(usec);
|
||||
@@ -53,13 +44,13 @@ static void testProcess_usleep(unsigned int usec)
|
||||
Sleep(usec / 1000);
|
||||
}
|
||||
#else
|
||||
# define testProcess_usleep usleep
|
||||
#define testProcess_usleep usleep
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
static void testProcess_sleep(unsigned int sec)
|
||||
{
|
||||
Sleep(sec*1000);
|
||||
Sleep(sec * 1000);
|
||||
}
|
||||
#else
|
||||
static void testProcess_sleep(unsigned int sec)
|
||||
@@ -68,10 +59,9 @@ static void testProcess_sleep(unsigned int sec)
|
||||
}
|
||||
#endif
|
||||
|
||||
int runChild(const char* cmd[], int state, int exception, int value,
|
||||
int share, int output, int delay, double timeout, int poll,
|
||||
int repeat, int disown, int createNewGroup,
|
||||
unsigned int interruptDelay);
|
||||
int runChild(const char* cmd[], int state, int exception, int value, int share,
|
||||
int output, int delay, double timeout, int poll, int repeat,
|
||||
int disown, int createNewGroup, unsigned int interruptDelay);
|
||||
|
||||
static int test1(int argc, const char* argv[])
|
||||
{
|
||||
@@ -85,7 +75,8 @@ static int test1(int argc, const char* argv[])
|
||||
If you have problems with this test timing out on your system, or want to
|
||||
run more than 257 iterations, you can change the number of iterations by
|
||||
setting the KWSYS_TEST_PROCESS_1_COUNT environment variable. */
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output on stdout from test returning 0.\n");
|
||||
fprintf(stderr, "Output on stderr from test returning 0.\n");
|
||||
return 0;
|
||||
@@ -93,7 +84,8 @@ static int test1(int argc, const char* argv[])
|
||||
|
||||
static int test2(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output on stdout from test returning 123.\n");
|
||||
fprintf(stderr, "Output on stderr from test returning 123.\n");
|
||||
return 123;
|
||||
@@ -101,7 +93,8 @@ static int test2(int argc, const char* argv[])
|
||||
|
||||
static int test3(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
|
||||
fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
|
||||
fflush(stdout);
|
||||
@@ -120,7 +113,7 @@ static int test4(int argc, const char* argv[])
|
||||
optimize away the write. We hope to 'outsmart' them by using
|
||||
'volatile' and a slightly larger address, based on a runtime value. */
|
||||
volatile int* invalidAddress = 0;
|
||||
invalidAddress += argc?1:2;
|
||||
invalidAddress += argc ? 1 : 2;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* Avoid error diagnostic popups since we are crashing on purpose. */
|
||||
@@ -129,7 +122,8 @@ static int test4(int argc, const char* argv[])
|
||||
/* Avoid error diagnostic popups since we are crashing on purpose. */
|
||||
disable_debugger(1);
|
||||
#endif
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output before crash on stdout from crash test.\n");
|
||||
fprintf(stderr, "Output before crash on stderr from crash test.\n");
|
||||
fflush(stdout);
|
||||
@@ -155,8 +149,8 @@ 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, 1, 1, 1, 0, 15, 0, 1, 0, 0, 0);
|
||||
r = runChild(cmd, kwsysProcess_State_Exception, kwsysProcess_Exception_Fault,
|
||||
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");
|
||||
fflush(stdout);
|
||||
@@ -164,24 +158,23 @@ static int test5(int argc, const char* argv[])
|
||||
return r;
|
||||
}
|
||||
|
||||
#define TEST6_SIZE (4096*2)
|
||||
#define TEST6_SIZE (4096 * 2)
|
||||
static void test6(int argc, const char* argv[])
|
||||
{
|
||||
int i;
|
||||
char runaway[TEST6_SIZE+1];
|
||||
(void)argc; (void)argv;
|
||||
for(i=0;i < TEST6_SIZE;++i)
|
||||
{
|
||||
char runaway[TEST6_SIZE + 1];
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
for (i = 0; i < TEST6_SIZE; ++i) {
|
||||
runaway[i] = '.';
|
||||
}
|
||||
}
|
||||
runaway[TEST6_SIZE] = '\n';
|
||||
|
||||
/* Generate huge amounts of output to test killing. */
|
||||
for(;;)
|
||||
{
|
||||
fwrite(runaway, 1, TEST6_SIZE+1, stdout);
|
||||
for (;;) {
|
||||
fwrite(runaway, 1, TEST6_SIZE + 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Define MINPOLL to be one more than the number of times output is
|
||||
@@ -191,7 +184,8 @@ static void test6(int argc, const char* argv[])
|
||||
#define MAXPOLL 20
|
||||
static int test7(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output on stdout before sleep.\n");
|
||||
fprintf(stderr, "Output on stderr before sleep.\n");
|
||||
fflush(stdout);
|
||||
@@ -231,7 +225,8 @@ static int test8(int argc, const char* argv[])
|
||||
|
||||
static int test8_grandchild(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
|
||||
fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
|
||||
fflush(stdout);
|
||||
@@ -266,9 +261,8 @@ static int test9(int argc, const char* argv[])
|
||||
fprintf(stderr, "Output on stderr before grandchild test.\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
r = runChild(cmd, kwsysProcess_State_Exited,
|
||||
kwsysProcess_Exception_None,
|
||||
0, 1, 1, 0, 30, 0, 1, 0, 0, 0);
|
||||
r = runChild(cmd, kwsysProcess_State_Exited, kwsysProcess_Exception_None, 0,
|
||||
1, 1, 0, 30, 0, 1, 0, 0, 0);
|
||||
/* This sleep will avoid a race condition between this function exiting
|
||||
normally and our Ctrl+C handler exiting abnormally after the process
|
||||
exits. */
|
||||
@@ -294,21 +288,20 @@ static BOOL WINAPI test9_grandchild_handler(DWORD dwCtrlType)
|
||||
static int test9_grandchild(int argc, const char* argv[])
|
||||
{
|
||||
/* The grandchild just sleeps for a few seconds while ignoring signals. */
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#if defined(_WIN32)
|
||||
if(!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE))
|
||||
{
|
||||
if (!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if(sigaction(SIGINT, &sa, 0) < 0)
|
||||
{
|
||||
if (sigaction(SIGINT, &sa, 0) < 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
|
||||
fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
|
||||
@@ -341,9 +334,9 @@ static int test10(int argc, const char* argv[])
|
||||
fprintf(stderr, "Output on stderr before grandchild test.\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
r = runChild(cmd, kwsysProcess_State_Exception,
|
||||
kwsysProcess_Exception_Interrupt,
|
||||
0, 1, 1, 0, 30, 0, 1, 0, 1, 0);
|
||||
r =
|
||||
runChild(cmd, kwsysProcess_State_Exception,
|
||||
kwsysProcess_Exception_Interrupt, 0, 1, 1, 0, 30, 0, 1, 0, 1, 0);
|
||||
fprintf(stdout, "Output on stdout after grandchild test.\n");
|
||||
fprintf(stderr, "Output on stderr after grandchild test.\n");
|
||||
fflush(stdout);
|
||||
@@ -354,7 +347,8 @@ static int test10(int argc, const char* argv[])
|
||||
static int test10_grandchild(int argc, const char* argv[])
|
||||
{
|
||||
/* The grandchild just sleeps for a few seconds and handles signals. */
|
||||
(void)argc; (void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
|
||||
fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
|
||||
fflush(stdout);
|
||||
@@ -368,11 +362,10 @@ static int test10_grandchild(int argc, const char* argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int runChild2(kwsysProcess* kp,
|
||||
const char* cmd[], int state, int exception, int value,
|
||||
int share, int output, int delay, double timeout,
|
||||
int poll, int disown, int createNewGroup,
|
||||
unsigned int interruptDelay)
|
||||
static int runChild2(kwsysProcess* kp, const char* cmd[], int state,
|
||||
int exception, int value, int share, int output,
|
||||
int delay, double timeout, int poll, int disown,
|
||||
int createNewGroup, unsigned int interruptDelay)
|
||||
{
|
||||
int result = 0;
|
||||
char* data = 0;
|
||||
@@ -380,146 +373,128 @@ static int runChild2(kwsysProcess* kp,
|
||||
double userTimeout = 0;
|
||||
double* pUserTimeout = 0;
|
||||
kwsysProcess_SetCommand(kp, cmd);
|
||||
if(timeout >= 0)
|
||||
{
|
||||
if (timeout >= 0) {
|
||||
kwsysProcess_SetTimeout(kp, timeout);
|
||||
}
|
||||
if(share)
|
||||
{
|
||||
}
|
||||
if (share) {
|
||||
kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1);
|
||||
kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1);
|
||||
}
|
||||
if(disown)
|
||||
{
|
||||
}
|
||||
if (disown) {
|
||||
kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1);
|
||||
}
|
||||
if(createNewGroup)
|
||||
{
|
||||
}
|
||||
if (createNewGroup) {
|
||||
kwsysProcess_SetOption(kp, kwsysProcess_Option_CreateProcessGroup, 1);
|
||||
}
|
||||
}
|
||||
kwsysProcess_Execute(kp);
|
||||
|
||||
if(poll)
|
||||
{
|
||||
if (poll) {
|
||||
pUserTimeout = &userTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
if(interruptDelay)
|
||||
{
|
||||
if (interruptDelay) {
|
||||
testProcess_sleep(interruptDelay);
|
||||
kwsysProcess_Interrupt(kp);
|
||||
}
|
||||
}
|
||||
|
||||
if(!share && !disown)
|
||||
{
|
||||
if (!share && !disown) {
|
||||
int p;
|
||||
while((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout)))
|
||||
{
|
||||
if(output)
|
||||
{
|
||||
if(poll && p == kwsysProcess_Pipe_Timeout)
|
||||
{
|
||||
while ((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout))) {
|
||||
if (output) {
|
||||
if (poll && p == kwsysProcess_Pipe_Timeout) {
|
||||
fprintf(stdout, "WaitForData timeout reached.\n");
|
||||
fflush(stdout);
|
||||
|
||||
/* Count the number of times we polled without getting data.
|
||||
If it is excessive then kill the child and fail. */
|
||||
if(++poll >= MAXPOLL)
|
||||
{
|
||||
fprintf(stdout, "Poll count reached limit %d.\n",
|
||||
MAXPOLL);
|
||||
if (++poll >= MAXPOLL) {
|
||||
fprintf(stdout, "Poll count reached limit %d.\n", MAXPOLL);
|
||||
kwsysProcess_Kill(kp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(data, 1, (size_t) length, stdout);
|
||||
} else {
|
||||
fwrite(data, 1, (size_t)length, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
if(poll)
|
||||
{
|
||||
}
|
||||
if (poll) {
|
||||
/* Delay to avoid busy loop during polling. */
|
||||
testProcess_usleep(100000);
|
||||
}
|
||||
if(delay)
|
||||
{
|
||||
/* Purposely sleeping only on Win32 to let pipe fill up. */
|
||||
}
|
||||
if (delay) {
|
||||
/* Purposely sleeping only on Win32 to let pipe fill up. */
|
||||
#if defined(_WIN32)
|
||||
testProcess_usleep(100000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(disown)
|
||||
{
|
||||
if (disown) {
|
||||
kwsysProcess_Disown(kp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
kwsysProcess_WaitForExit(kp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
switch (kwsysProcess_GetState(kp))
|
||||
{
|
||||
switch (kwsysProcess_GetState(kp)) {
|
||||
case kwsysProcess_State_Starting:
|
||||
printf("No process has been executed.\n"); break;
|
||||
printf("No process has been executed.\n");
|
||||
break;
|
||||
case kwsysProcess_State_Executing:
|
||||
printf("The process is still executing.\n"); break;
|
||||
printf("The process is still executing.\n");
|
||||
break;
|
||||
case kwsysProcess_State_Expired:
|
||||
printf("Child was killed when timeout expired.\n"); break;
|
||||
printf("Child was killed when timeout expired.\n");
|
||||
break;
|
||||
case kwsysProcess_State_Exited:
|
||||
printf("Child exited with value = %d\n",
|
||||
kwsysProcess_GetExitValue(kp));
|
||||
printf("Child exited with value = %d\n", kwsysProcess_GetExitValue(kp));
|
||||
result = ((exception != kwsysProcess_GetExitException(kp)) ||
|
||||
(value != kwsysProcess_GetExitValue(kp))); break;
|
||||
(value != kwsysProcess_GetExitValue(kp)));
|
||||
break;
|
||||
case kwsysProcess_State_Killed:
|
||||
printf("Child was killed by parent.\n"); break;
|
||||
printf("Child was killed by parent.\n");
|
||||
break;
|
||||
case kwsysProcess_State_Exception:
|
||||
printf("Child terminated abnormally: %s\n",
|
||||
kwsysProcess_GetExceptionString(kp));
|
||||
result = ((exception != kwsysProcess_GetExitException(kp)) ||
|
||||
(value != kwsysProcess_GetExitValue(kp))); break;
|
||||
(value != kwsysProcess_GetExitValue(kp)));
|
||||
break;
|
||||
case kwsysProcess_State_Disowned:
|
||||
printf("Child was disowned.\n"); break;
|
||||
printf("Child was disowned.\n");
|
||||
break;
|
||||
case kwsysProcess_State_Error:
|
||||
printf("Error in administrating child process: [%s]\n",
|
||||
kwsysProcess_GetErrorString(kp)); break;
|
||||
};
|
||||
kwsysProcess_GetErrorString(kp));
|
||||
break;
|
||||
};
|
||||
|
||||
if(result)
|
||||
{
|
||||
if(exception != kwsysProcess_GetExitException(kp))
|
||||
{
|
||||
if (result) {
|
||||
if (exception != kwsysProcess_GetExitException(kp)) {
|
||||
fprintf(stderr, "Mismatch in exit exception. "
|
||||
"Should have been %d, was %d.\n",
|
||||
"Should have been %d, was %d.\n",
|
||||
exception, kwsysProcess_GetExitException(kp));
|
||||
}
|
||||
if(value != kwsysProcess_GetExitValue(kp))
|
||||
{
|
||||
fprintf(stderr, "Mismatch in exit value. "
|
||||
"Should have been %d, was %d.\n",
|
||||
value, kwsysProcess_GetExitValue(kp));
|
||||
}
|
||||
}
|
||||
if (value != kwsysProcess_GetExitValue(kp)) {
|
||||
fprintf(stderr, "Mismatch in exit value. "
|
||||
"Should have been %d, was %d.\n",
|
||||
value, kwsysProcess_GetExitValue(kp));
|
||||
}
|
||||
}
|
||||
|
||||
if(kwsysProcess_GetState(kp) != state)
|
||||
{
|
||||
if (kwsysProcess_GetState(kp) != state) {
|
||||
fprintf(stderr, "Mismatch in state. "
|
||||
"Should have been %d, was %d.\n",
|
||||
"Should have been %d, was %d.\n",
|
||||
state, kwsysProcess_GetState(kp));
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should have polled more times than there were data if polling
|
||||
was enabled. */
|
||||
if(poll && poll < MINPOLL)
|
||||
{
|
||||
fprintf(stderr, "Poll count is %d, which is less than %d.\n",
|
||||
poll, MINPOLL);
|
||||
if (poll && poll < MINPOLL) {
|
||||
fprintf(stderr, "Poll count is %d, which is less than %d.\n", poll,
|
||||
MINPOLL);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -551,28 +526,23 @@ static int runChild2(kwsysProcess* kp,
|
||||
* BEFORE any reading/polling of pipes occurs and before any
|
||||
* detachment occurs.
|
||||
*/
|
||||
int runChild(const char* cmd[], int state, int exception, int value,
|
||||
int share, int output, int delay, double timeout,
|
||||
int poll, int repeat, int disown, int createNewGroup,
|
||||
unsigned int interruptDelay)
|
||||
int runChild(const char* cmd[], int state, int exception, int value, int share,
|
||||
int output, int delay, double timeout, int poll, int repeat,
|
||||
int disown, int createNewGroup, unsigned int interruptDelay)
|
||||
{
|
||||
int result = 1;
|
||||
kwsysProcess* kp = kwsysProcess_New();
|
||||
if(!kp)
|
||||
{
|
||||
if (!kp) {
|
||||
fprintf(stderr, "kwsysProcess_New returned NULL!\n");
|
||||
return 1;
|
||||
}
|
||||
while(repeat-- > 0)
|
||||
{
|
||||
result = runChild2(kp, cmd, state, exception, value, share,
|
||||
output, delay, timeout, poll, disown, createNewGroup,
|
||||
interruptDelay);
|
||||
if(result)
|
||||
{
|
||||
}
|
||||
while (repeat-- > 0) {
|
||||
result = runChild2(kp, cmd, state, exception, value, share, output, delay,
|
||||
timeout, poll, disown, createNewGroup, interruptDelay);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kwsysProcess_Delete(kp);
|
||||
return result;
|
||||
}
|
||||
@@ -585,8 +555,7 @@ int main(int argc, const char* argv[])
|
||||
int i;
|
||||
char new_args[10][_MAX_PATH];
|
||||
LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
for(i=0; i<argc; i++)
|
||||
{
|
||||
for (i = 0; i < argc; i++) {
|
||||
kwsysEncoding_wcstombs(new_args[i], w_av[i], _MAX_PATH);
|
||||
argv[i] = new_args[i];
|
||||
}
|
||||
@@ -609,107 +578,96 @@ int main(int argc, const char* argv[])
|
||||
SetStdHandle(STD_ERROR_HANDLE, out);
|
||||
}
|
||||
#endif
|
||||
if(argc == 2)
|
||||
{
|
||||
if (argc == 2) {
|
||||
n = atoi(argv[1]);
|
||||
}
|
||||
else if(argc == 3 && strcmp(argv[1], "run") == 0)
|
||||
{
|
||||
} else if (argc == 3 && strcmp(argv[1], "run") == 0) {
|
||||
n = atoi(argv[2]);
|
||||
}
|
||||
}
|
||||
/* Check arguments. */
|
||||
if(((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3)
|
||||
{
|
||||
if (((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3) {
|
||||
/* This is the child process for a requested test number. */
|
||||
switch (n)
|
||||
{
|
||||
case 1: return test1(argc, argv);
|
||||
case 2: return test2(argc, argv);
|
||||
case 3: return test3(argc, argv);
|
||||
case 4: return test4(argc, argv);
|
||||
case 5: return test5(argc, argv);
|
||||
case 6: test6(argc, argv); return 0;
|
||||
case 7: return test7(argc, argv);
|
||||
case 8: return test8(argc, argv);
|
||||
case 9: return test9(argc, argv);
|
||||
case 10: return test10(argc, argv);
|
||||
case 108: return test8_grandchild(argc, argv);
|
||||
case 109: return test9_grandchild(argc, argv);
|
||||
case 110: return test10_grandchild(argc, argv);
|
||||
}
|
||||
switch (n) {
|
||||
case 1:
|
||||
return test1(argc, argv);
|
||||
case 2:
|
||||
return test2(argc, argv);
|
||||
case 3:
|
||||
return test3(argc, argv);
|
||||
case 4:
|
||||
return test4(argc, argv);
|
||||
case 5:
|
||||
return test5(argc, argv);
|
||||
case 6:
|
||||
test6(argc, argv);
|
||||
return 0;
|
||||
case 7:
|
||||
return test7(argc, argv);
|
||||
case 8:
|
||||
return test8(argc, argv);
|
||||
case 9:
|
||||
return test9(argc, argv);
|
||||
case 10:
|
||||
return test10(argc, argv);
|
||||
case 108:
|
||||
return test8_grandchild(argc, argv);
|
||||
case 109:
|
||||
return test9_grandchild(argc, argv);
|
||||
case 110:
|
||||
return test10_grandchild(argc, argv);
|
||||
}
|
||||
fprintf(stderr, "Invalid test number %d.\n", n);
|
||||
return 1;
|
||||
}
|
||||
else if(n >= 1 && n <= 10)
|
||||
{
|
||||
} else if (n >= 1 && n <= 10) {
|
||||
/* This is the parent process for a requested test number. */
|
||||
int states[10] =
|
||||
{
|
||||
kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Expired,
|
||||
kwsysProcess_State_Exception,
|
||||
kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Expired,
|
||||
kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Expired, /* Ctrl+C handler test */
|
||||
int states[10] = {
|
||||
kwsysProcess_State_Exited, kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Expired, kwsysProcess_State_Exception,
|
||||
kwsysProcess_State_Exited, kwsysProcess_State_Expired,
|
||||
kwsysProcess_State_Exited, kwsysProcess_State_Exited,
|
||||
kwsysProcess_State_Expired, /* Ctrl+C handler test */
|
||||
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
|
||||
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
|
||||
};
|
||||
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};
|
||||
int outputs[10] = {1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
|
||||
int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
|
||||
double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4};
|
||||
int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
|
||||
int repeat[10] = {257, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
|
||||
unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2};
|
||||
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 };
|
||||
int outputs[10] = { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 };
|
||||
int delays[10] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };
|
||||
double timeouts[10] = { 10, 10, 10, 30, 30, 10, -1, 10, 6, 4 };
|
||||
int polls[10] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
|
||||
int repeat[10] = { 257, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
int createNewGroups[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
|
||||
unsigned int interruptDelays[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 3, 2 };
|
||||
int r;
|
||||
const char* cmd[4];
|
||||
#ifdef _WIN32
|
||||
char* argv0 = 0;
|
||||
#endif
|
||||
char* test1IterationsStr = getenv("KWSYS_TEST_PROCESS_1_COUNT");
|
||||
if(test1IterationsStr)
|
||||
{
|
||||
if (test1IterationsStr) {
|
||||
long int test1Iterations = strtol(test1IterationsStr, 0, 10);
|
||||
if(test1Iterations > 10 && test1Iterations != LONG_MAX)
|
||||
{
|
||||
if (test1Iterations > 10 && test1Iterations != LONG_MAX) {
|
||||
repeat[0] = (int)test1Iterations;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if(n == 0 && (argv0 = strdup(argv[0])))
|
||||
{
|
||||
if (n == 0 && (argv0 = strdup(argv[0]))) {
|
||||
/* Try converting to forward slashes to see if it works. */
|
||||
char* c;
|
||||
for(c=argv0; *c; ++c)
|
||||
{
|
||||
if(*c == '\\')
|
||||
{
|
||||
for (c = argv0; *c; ++c) {
|
||||
if (*c == '\\') {
|
||||
*c = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd[0] = argv0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cmd[0] = argv[0];
|
||||
}
|
||||
}
|
||||
#else
|
||||
cmd[0] = argv[0];
|
||||
#endif
|
||||
@@ -720,36 +678,34 @@ int main(int argc, const char* argv[])
|
||||
fprintf(stderr, "Output on stderr before test %d.\n", n);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], shares[n-1],
|
||||
outputs[n-1], delays[n-1], timeouts[n-1],
|
||||
polls[n-1], repeat[n-1], 0, createNewGroups[n-1],
|
||||
interruptDelays[n-1]);
|
||||
r = runChild(cmd, states[n - 1], exceptions[n - 1], values[n - 1],
|
||||
shares[n - 1], outputs[n - 1], delays[n - 1], timeouts[n - 1],
|
||||
polls[n - 1], repeat[n - 1], 0, createNewGroups[n - 1],
|
||||
interruptDelays[n - 1]);
|
||||
fprintf(stdout, "Output on stdout after test %d.\n", n);
|
||||
fprintf(stderr, "Output on stderr after test %d.\n", n);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
#if defined(_WIN32)
|
||||
if(argv0) { free(argv0); }
|
||||
if (argv0) {
|
||||
free(argv0);
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
else if(argc > 2 && strcmp(argv[1], "0") == 0)
|
||||
{
|
||||
} else if (argc > 2 && strcmp(argv[1], "0") == 0) {
|
||||
/* This is the special debugging test to run a given command
|
||||
line. */
|
||||
const char** cmd = argv+2;
|
||||
const char** cmd = argv + 2;
|
||||
int state = kwsysProcess_State_Exited;
|
||||
int exception = kwsysProcess_Exception_None;
|
||||
int value = 0;
|
||||
double timeout = 0;
|
||||
int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout,
|
||||
0, 1, 0, 0, 0);
|
||||
int r =
|
||||
runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0, 0, 0);
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Improper usage. */
|
||||
fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,24 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#if defined(CMAKE_INTDIR)
|
||||
# define CONFIG_DIR_PRE CMAKE_INTDIR "/"
|
||||
# define CONFIG_DIR_POST "/" CMAKE_INTDIR
|
||||
#define CONFIG_DIR_PRE CMAKE_INTDIR "/"
|
||||
#define CONFIG_DIR_POST "/" CMAKE_INTDIR
|
||||
#else
|
||||
# define CONFIG_DIR_PRE ""
|
||||
# define CONFIG_DIR_POST ""
|
||||
#define CONFIG_DIR_PRE ""
|
||||
#define CONFIG_DIR_POST ""
|
||||
#endif
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "@EXEC_DIR@"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL 0
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD \
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD \
|
||||
CONFIG_DIR_PRE "@KWSYS_NAMESPACE@TestProcess"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL \
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL \
|
||||
"@KWSYS_NAMESPACE@TestProcess"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print"
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd"
|
||||
#if defined(CMAKE_INTDIR)
|
||||
# define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR
|
||||
#define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR
|
||||
#endif
|
||||
#include <@KWSYS_NAMESPACE@/SharedForward.h>
|
||||
int main(int argc, char** argv)
|
||||
|
||||
@@ -1,51 +1,41 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(SystemInformation.hxx)
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "SystemInformation.hxx.in"
|
||||
#include "SystemInformation.hxx.in"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(KWSYS_USE_LONG_LONG)
|
||||
# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
|
||||
# define iostreamLongLong(x) (x)
|
||||
# else
|
||||
# define iostreamLongLong(x) ((long)x)
|
||||
# endif
|
||||
#elif defined(KWSYS_USE___INT64)
|
||||
# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
|
||||
# define iostreamLongLong(x) (x)
|
||||
# else
|
||||
# define iostreamLongLong(x) ((long)x)
|
||||
# endif
|
||||
#if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
|
||||
#define iostreamLongLong(x) (x)
|
||||
#else
|
||||
# error "No Long Long"
|
||||
#define iostreamLongLong(x) ((long)x)
|
||||
#endif
|
||||
#elif defined(KWSYS_USE___INT64)
|
||||
#if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
|
||||
#define iostreamLongLong(x) (x)
|
||||
#else
|
||||
#define iostreamLongLong(x) ((long)x)
|
||||
#endif
|
||||
#else
|
||||
#error "No Long Long"
|
||||
#endif
|
||||
|
||||
#define printMethod(info, m) std::cout << #m << ": " \
|
||||
<< info.m() << "\n"
|
||||
#define printMethod(info, m) std::cout << #m << ": " << info.m() << "\n"
|
||||
|
||||
#define printMethod2(info, m, unit) std::cout << #m << ": " \
|
||||
<< info.m() << " " << unit << "\n"
|
||||
#define printMethod2(info, m, unit) \
|
||||
std::cout << #m << ": " << info.m() << " " << unit << "\n"
|
||||
|
||||
#define printMethod3(info, m, unit) std::cout << #m << ": " \
|
||||
<< iostreamLongLong(info.m) << " " << unit << "\n"
|
||||
#define printMethod3(info, m, unit) \
|
||||
std::cout << #m << ": " << iostreamLongLong(info.m) << " " << unit << "\n"
|
||||
|
||||
int testSystemInformation(int, char*[])
|
||||
int testSystemInformation(int, char* [])
|
||||
{
|
||||
std::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
|
||||
|
||||
@@ -84,25 +74,22 @@ int testSystemInformation(int, char*[])
|
||||
printMethod2(info, GetAvailablePhysicalMemory, "MB");
|
||||
printMethod3(info, GetHostMemoryTotal(), "KiB");
|
||||
printMethod3(info, GetHostMemoryAvailable("KWSHL"), "KiB");
|
||||
printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
|
||||
printMethod3(info, GetProcMemoryAvailable("KWSHL", "KWSPL"), "KiB");
|
||||
printMethod3(info, GetHostMemoryUsed(), "KiB");
|
||||
printMethod3(info, GetProcMemoryUsed(), "KiB");
|
||||
printMethod(info, GetLoadAverage);
|
||||
|
||||
for (long int i = 0; i <= 31; i++)
|
||||
{
|
||||
if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i))
|
||||
{
|
||||
for (long int i = 0; i <= 31; i++) {
|
||||
if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i)) {
|
||||
std::cout << "CPU feature " << i << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* test stack trace
|
||||
*/
|
||||
std::cout
|
||||
<< "Program Stack:" << std::endl
|
||||
<< kwsys::SystemInformation::GetProgramStack(0,0) << std::endl
|
||||
<< std::endl;
|
||||
std::cout << "Program Stack:" << std::endl
|
||||
<< kwsys::SystemInformation::GetProgramStack(0, 0) << std::endl
|
||||
<< std::endl;
|
||||
|
||||
/* test segv handler
|
||||
info.SetStackTraceOnError(1);
|
||||
|
||||
+451
-677
@@ -1,18 +1,9 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (disable:4786)
|
||||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#include KWSYS_HEADER(SystemTools.hxx)
|
||||
@@ -20,7 +11,7 @@
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
#if 0
|
||||
# include "SystemTools.hxx.in"
|
||||
#include "SystemTools.hxx.in"
|
||||
#endif
|
||||
|
||||
// Include with <> instead of "" to avoid getting any in-source copy
|
||||
@@ -31,77 +22,65 @@
|
||||
#include <sstream>
|
||||
#include <string.h> /* strcmp */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include <io.h> /* _umask (MSVC) / umask (Borland) */
|
||||
# ifdef _MSC_VER
|
||||
# define umask _umask // Note this is still umask on Borland
|
||||
# endif
|
||||
#include <io.h> /* _umask (MSVC) / umask (Borland) */
|
||||
#ifdef _MSC_VER
|
||||
#define umask _umask // Note this is still umask on Borland
|
||||
#endif
|
||||
#endif
|
||||
#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
|
||||
// Visual C++ does not define mode_t (note that Borland does, however).
|
||||
#if defined( _MSC_VER )
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* toUnixPaths[][2] =
|
||||
{
|
||||
{ "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
|
||||
{ "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
|
||||
{ "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" },
|
||||
{ "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" },
|
||||
{ "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" },
|
||||
{ "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" },
|
||||
{ "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" },
|
||||
{ "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" },
|
||||
{ "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
|
||||
{ "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
|
||||
{ "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{0, 0}
|
||||
static const char* toUnixPaths[][2] = {
|
||||
{ "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
|
||||
{ "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
|
||||
{ "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" },
|
||||
{ "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" },
|
||||
{ "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" },
|
||||
{ "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" },
|
||||
{ "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" },
|
||||
{ "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" },
|
||||
{ "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
|
||||
{ "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
|
||||
{ "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo\\ cal/bin/pa\\ sswd" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static bool CheckConvertToUnixSlashes(std::string input,
|
||||
std::string output)
|
||||
static bool CheckConvertToUnixSlashes(std::string input, std::string output)
|
||||
{
|
||||
std::string result = input;
|
||||
kwsys::SystemTools::ConvertToUnixSlashes(result);
|
||||
if ( result != output )
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToUnixSlashes - input: " << input
|
||||
<< " output: " << result << " expected: " << output
|
||||
<< std::endl;
|
||||
if (result != output) {
|
||||
std::cerr << "Problem with ConvertToUnixSlashes - input: " << input
|
||||
<< " output: " << result << " expected: " << output << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* checkEscapeChars[][4] =
|
||||
{
|
||||
{ "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2"},
|
||||
{ " {} ", "{}", "#", " #{#} "},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
static const char* checkEscapeChars[][4] = { { "1 foo 2 bar 2", "12", "\\",
|
||||
"\\1 foo \\2 bar \\2" },
|
||||
{ " {} ", "{}", "#", " #{#} " },
|
||||
{ 0, 0, 0, 0 } };
|
||||
|
||||
static bool CheckEscapeChars(std::string input,
|
||||
const char *chars_to_escape,
|
||||
char escape_char,
|
||||
std::string output)
|
||||
static bool CheckEscapeChars(std::string input, const char* chars_to_escape,
|
||||
char escape_char, std::string output)
|
||||
{
|
||||
std::string result = kwsys::SystemTools::EscapeChars(
|
||||
input.c_str(), chars_to_escape, escape_char);
|
||||
if (result != output)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with CheckEscapeChars - input: " << input
|
||||
<< " output: " << result << " expected: " << output
|
||||
<< std::endl;
|
||||
if (result != output) {
|
||||
std::cerr << "Problem with CheckEscapeChars - input: " << input
|
||||
<< " output: " << result << " expected: " << output << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,268 +89,192 @@ static bool CheckFileOperations()
|
||||
{
|
||||
bool res = true;
|
||||
const std::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR
|
||||
"/testSystemToolsNonExistingFile");
|
||||
const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR
|
||||
"/.");
|
||||
"/testSystemToolsNonExistingFile");
|
||||
const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR "/.");
|
||||
const std::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
|
||||
"/testSystemTools.bin");
|
||||
"/testSystemTools.bin");
|
||||
const std::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
|
||||
"/testSystemTools.cxx");
|
||||
"/testSystemTools.cxx");
|
||||
const std::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
|
||||
"/testSystemToolsNewDir");
|
||||
"/testSystemToolsNewDir");
|
||||
const std::string testNewFile(testNewDir + "/testNewFile.txt");
|
||||
|
||||
if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) !=
|
||||
kwsys::SystemTools::FileTypeUnknown)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testNonExistingFile << std::endl;
|
||||
kwsys::SystemTools::FileTypeUnknown) {
|
||||
std::cerr << "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testNonExistingFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) !=
|
||||
kwsys::SystemTools::FileTypeUnknown)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testDotFile << std::endl;
|
||||
kwsys::SystemTools::FileTypeUnknown) {
|
||||
std::cerr << "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testDotFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
|
||||
kwsys::SystemTools::FileTypeBinary)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testBinFile << std::endl;
|
||||
kwsys::SystemTools::FileTypeBinary) {
|
||||
std::cerr << "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testBinFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
|
||||
kwsys::SystemTools::FileTypeText)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testTxtFile << std::endl;
|
||||
kwsys::SystemTools::FileTypeText) {
|
||||
std::cerr << "Problem with DetectFileType - failed to detect type of: "
|
||||
<< testTxtFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::FileLength(testBinFile) != 766)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileLength - incorrect length for: "
|
||||
<< testBinFile << std::endl;
|
||||
if (kwsys::SystemTools::FileLength(testBinFile) != 766) {
|
||||
std::cerr << "Problem with FileLength - incorrect length for: "
|
||||
<< testBinFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with MakeDirectory for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir)) {
|
||||
std::cerr << "Problem with MakeDirectory for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// calling it again should just return true
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with second call to MakeDirectory for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir)) {
|
||||
std::cerr << "Problem with second call to MakeDirectory for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// calling with 0 pointer should return false
|
||||
if (kwsys::SystemTools::MakeDirectory(0))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with MakeDirectory(0)"
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::MakeDirectory(0)) {
|
||||
std::cerr << "Problem with MakeDirectory(0)" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// calling with an empty string should return false
|
||||
if (kwsys::SystemTools::MakeDirectory(std::string()))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with MakeDirectory(std::string())"
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::MakeDirectory(std::string())) {
|
||||
std::cerr << "Problem with MakeDirectory(std::string())" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// check existence
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
|
||||
std::cerr << "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// check existence
|
||||
if (!kwsys::SystemTools::PathExists(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with PathExists for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::PathExists(testNewDir)) {
|
||||
std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// remove it
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveADirectory for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
|
||||
std::cerr << "Problem with RemoveADirectory for: " << testNewDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// check existence
|
||||
if (kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
|
||||
{
|
||||
std::cerr
|
||||
<< "After RemoveADirectory: "
|
||||
<< "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
|
||||
std::cerr << "After RemoveADirectory: "
|
||||
<< "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// check existence
|
||||
if (kwsys::SystemTools::PathExists(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "After RemoveADirectory: "
|
||||
<< "Problem with PathExists for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (kwsys::SystemTools::PathExists(testNewDir)) {
|
||||
std::cerr << "After RemoveADirectory: "
|
||||
<< "Problem with PathExists for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// create it using the char* version
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str()))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with second call to MakeDirectory as C string for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str())) {
|
||||
std::cerr << "Problem with second call to MakeDirectory as C string for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with Touch for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true)) {
|
||||
std::cerr << "Problem with Touch for: " << testNewFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// calling MakeDirectory with something that is no file should fail
|
||||
if (kwsys::SystemTools::MakeDirectory(testNewFile))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with to MakeDirectory for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (kwsys::SystemTools::MakeDirectory(testNewFile)) {
|
||||
std::cerr << "Problem with to MakeDirectory for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// calling with 0 pointer should return false
|
||||
if (kwsys::SystemTools::FileExists(0))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists(0)"
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::FileExists(0)) {
|
||||
std::cerr << "Problem with FileExists(0)" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (kwsys::SystemTools::FileExists(0, true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists(0) as file"
|
||||
<< std::endl;
|
||||
}
|
||||
if (kwsys::SystemTools::FileExists(0, true)) {
|
||||
std::cerr << "Problem with FileExists(0) as file" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// calling with an empty string should return false
|
||||
if (kwsys::SystemTools::FileExists(std::string()))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists(std::string())"
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::FileExists(std::string())) {
|
||||
std::cerr << "Problem with FileExists(std::string())" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// FileExists(x, true) should return false on a directory
|
||||
if (kwsys::SystemTools::FileExists(testNewDir, true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as file for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (kwsys::SystemTools::FileExists(testNewDir, true)) {
|
||||
std::cerr << "Problem with FileExists as file for: " << testNewDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (kwsys::SystemTools::FileExists(testNewDir.c_str(), true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as C string and file for: "
|
||||
<< testNewDir << std::endl;
|
||||
}
|
||||
if (kwsys::SystemTools::FileExists(testNewDir.c_str(), true)) {
|
||||
std::cerr << "Problem with FileExists as C string and file for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// FileExists(x, false) should return true even on a directory
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir, false))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir, false)) {
|
||||
std::cerr << "Problem with FileExists as not file for: " << testNewDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
|
||||
std::cerr << "Problem with FileExists as C string and not file for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// should work, was created as new file before
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile)) {
|
||||
std::cerr << "Problem with FileExists for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile.c_str()))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as C string for: "
|
||||
<< testNewDir << std::endl;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) {
|
||||
std::cerr << "Problem with FileExists as C string for: " << testNewDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile, true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FileExists as file for: "
|
||||
<< testNewDir << std::endl;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile, true)) {
|
||||
std::cerr << "Problem with FileExists as file for: " << testNewDir
|
||||
<< 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;
|
||||
}
|
||||
if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) {
|
||||
std::cerr << "Problem with FileExists as C string and file for: "
|
||||
<< testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// calling with an empty string should return false
|
||||
if (kwsys::SystemTools::PathExists(std::string()))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with PathExists(std::string())"
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::PathExists(std::string())) {
|
||||
std::cerr << "Problem with PathExists(std::string())" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// PathExists(x) should return true on a directory
|
||||
if (!kwsys::SystemTools::PathExists(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with PathExists for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::PathExists(testNewDir)) {
|
||||
std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
// should work, was created as new file before
|
||||
if (!kwsys::SystemTools::PathExists(testNewFile))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with PathExists for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::PathExists(testNewFile)) {
|
||||
std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset umask
|
||||
// Reset umask
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
// NOTE: Windows doesn't support toggling _S_IREAD.
|
||||
mode_t fullMask = _S_IWRITE;
|
||||
@@ -383,208 +286,169 @@ static bool CheckFileOperations()
|
||||
|
||||
// Test file permissions without umask
|
||||
mode_t origPerm, thisPerm;
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with GetPermissions (1) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm)) {
|
||||
std::cerr << "Problem with GetPermissions (1) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, 0))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with SetPermissions (1) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, 0)) {
|
||||
std::cerr << "Problem with SetPermissions (1) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with GetPermissions (2) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
|
||||
std::cerr << "Problem with GetPermissions (2) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((thisPerm & fullMask) != 0)
|
||||
{
|
||||
std::cerr
|
||||
<< "SetPermissions failed to set permissions (1) for: "
|
||||
<< testNewFile << ": actual = " << thisPerm << "; expected = "
|
||||
<< 0 << std::endl;
|
||||
if ((thisPerm & fullMask) != 0) {
|
||||
std::cerr << "SetPermissions failed to set permissions (1) for: "
|
||||
<< testNewFile << ": actual = " << thisPerm
|
||||
<< "; expected = " << 0 << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// While we're at it, check proper TestFileAccess functionality.
|
||||
if (kwsys::SystemTools::TestFileAccess(testNewFile,
|
||||
kwsys::TEST_FILE_WRITE))
|
||||
{
|
||||
kwsys::TEST_FILE_WRITE)) {
|
||||
std::cerr
|
||||
<< "TestFileAccess incorrectly indicated that this is a writable file:"
|
||||
<< testNewFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::TestFileAccess(testNewFile,
|
||||
kwsys::TEST_FILE_OK))
|
||||
{
|
||||
if (!kwsys::SystemTools::TestFileAccess(testNewFile, kwsys::TEST_FILE_OK)) {
|
||||
std::cerr
|
||||
<< "TestFileAccess incorrectly indicated that this file does not exist:"
|
||||
<< testNewFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test restoring/setting full permissions.
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with SetPermissions (2) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask)) {
|
||||
std::cerr << "Problem with SetPermissions (2) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with GetPermissions (3) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
|
||||
std::cerr << "Problem with GetPermissions (3) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((thisPerm & fullMask) != fullMask)
|
||||
{
|
||||
std::cerr
|
||||
<< "SetPermissions failed to set permissions (2) for: "
|
||||
<< testNewFile << ": actual = " << thisPerm << "; expected = "
|
||||
<< fullMask << std::endl;
|
||||
if ((thisPerm & fullMask) != fullMask) {
|
||||
std::cerr << "SetPermissions failed to set permissions (2) for: "
|
||||
<< testNewFile << ": actual = " << thisPerm
|
||||
<< "; expected = " << fullMask << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test setting file permissions while honoring umask
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with SetPermissions (3) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true)) {
|
||||
std::cerr << "Problem with SetPermissions (3) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with GetPermissions (4) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
|
||||
std::cerr << "Problem with GetPermissions (4) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((thisPerm & fullMask) != 0)
|
||||
{
|
||||
std::cerr
|
||||
<< "SetPermissions failed to honor umask for: "
|
||||
<< testNewFile << ": actual = " << thisPerm << "; expected = "
|
||||
<< 0 << std::endl;
|
||||
if ((thisPerm & fullMask) != 0) {
|
||||
std::cerr << "SetPermissions failed to honor umask for: " << testNewFile
|
||||
<< ": actual = " << thisPerm << "; expected = " << 0
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore umask
|
||||
umask(orig_umask);
|
||||
|
||||
// Restore file permissions
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with SetPermissions (4) for: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm)) {
|
||||
std::cerr << "Problem with SetPermissions (4) for: " << testNewFile
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the test file
|
||||
if (!kwsys::SystemTools::RemoveFile(testNewFile))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveFile: "
|
||||
<< testNewFile << std::endl;
|
||||
if (!kwsys::SystemTools::RemoveFile(testNewFile)) {
|
||||
std::cerr << "Problem with RemoveFile: " << testNewFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string const testFileMissing(testNewDir + "/testMissingFile.txt");
|
||||
if (!kwsys::SystemTools::RemoveFile(testFileMissing))
|
||||
{
|
||||
if (!kwsys::SystemTools::RemoveFile(testFileMissing)) {
|
||||
std::string const& msg = kwsys::SystemTools::GetLastSystemError();
|
||||
std::cerr <<
|
||||
"RemoveFile(\"" << testFileMissing << "\") failed: " << msg << "\n";
|
||||
std::cerr << "RemoveFile(\"" << testFileMissing << "\") failed: " << msg
|
||||
<< "\n";
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string const testFileMissingDir(testNewDir + "/missing/file.txt");
|
||||
if (!kwsys::SystemTools::RemoveFile(testFileMissingDir))
|
||||
{
|
||||
if (!kwsys::SystemTools::RemoveFile(testFileMissingDir)) {
|
||||
std::string const& msg = kwsys::SystemTools::GetLastSystemError();
|
||||
std::cerr <<
|
||||
"RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg << "\n";
|
||||
std::cerr << "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg
|
||||
<< "\n";
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
kwsys::SystemTools::Touch(testNewFile.c_str(), true);
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveADirectory for: "
|
||||
<< testNewDir << std::endl;
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
|
||||
std::cerr << "Problem with RemoveADirectory for: " << testNewDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
|
||||
// Perform the same file and directory creation and deletion tests but
|
||||
// with paths > 256 characters in length.
|
||||
|
||||
const std::string testNewLongDir(
|
||||
TEST_SYSTEMTOOLS_BINARY_DIR "/"
|
||||
TEST_SYSTEMTOOLS_BINARY_DIR
|
||||
"/"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"01234567890123");
|
||||
const std::string testNewLongFile(testNewLongDir + "/"
|
||||
const std::string testNewLongFile(
|
||||
testNewLongDir +
|
||||
"/"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"012345678901234567890123456789012345678901234567890123456789"
|
||||
"0123456789.txt");
|
||||
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewLongDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with MakeDirectory for: "
|
||||
<< testNewLongDir << std::endl;
|
||||
if (!kwsys::SystemTools::MakeDirectory(testNewLongDir)) {
|
||||
std::cerr << "Problem with MakeDirectory for: " << testNewLongDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with Touch for: "
|
||||
<< testNewLongFile << std::endl;
|
||||
if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true)) {
|
||||
std::cerr << "Problem with Touch for: " << testNewLongFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::RemoveFile(testNewLongFile))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveFile: "
|
||||
<< testNewLongFile << std::endl;
|
||||
if (!kwsys::SystemTools::RemoveFile(testNewLongFile)) {
|
||||
std::cerr << "Problem with RemoveFile: " << testNewLongFile << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveADirectory for: "
|
||||
<< testNewLongDir << std::endl;
|
||||
if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir)) {
|
||||
std::cerr << "Problem with RemoveADirectory for: " << testNewLongDir
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
@@ -596,326 +460,254 @@ static bool CheckStringOperations()
|
||||
bool res = true;
|
||||
|
||||
std::string test = "mary had a little lamb.";
|
||||
if (kwsys::SystemTools::CapitalizedWords(test) != "Mary Had A Little Lamb.")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with CapitalizedWords "
|
||||
<< '"' << test << '"' << std::endl;
|
||||
if (kwsys::SystemTools::CapitalizedWords(test) !=
|
||||
"Mary Had A Little Lamb.") {
|
||||
std::cerr << "Problem with CapitalizedWords " << '"' << test << '"'
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
test = "Mary Had A Little Lamb.";
|
||||
if (kwsys::SystemTools::UnCapitalizedWords(test) !=
|
||||
"mary had a little lamb.")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with UnCapitalizedWords "
|
||||
<< '"' << test << '"' << std::endl;
|
||||
"mary had a little lamb.") {
|
||||
std::cerr << "Problem with UnCapitalizedWords " << '"' << test << '"'
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
test = "MaryHadTheLittleLamb.";
|
||||
if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
|
||||
"Mary Had The Little Lamb.")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with AddSpaceBetweenCapitalizedWords "
|
||||
<< '"' << test << '"' << std::endl;
|
||||
"Mary Had The Little Lamb.") {
|
||||
std::cerr << "Problem with AddSpaceBetweenCapitalizedWords " << '"' << test
|
||||
<< '"' << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
char * cres =
|
||||
kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb.");
|
||||
if (strcmp(cres,"Mary Had A Little Lamb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with AppendStrings "
|
||||
<< "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
|
||||
char* cres =
|
||||
kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb.");
|
||||
if (strcmp(cres, "Mary Had A Little Lamb.")) {
|
||||
std::cerr << "Problem with AppendStrings "
|
||||
<< "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres;
|
||||
}
|
||||
delete[] cres;
|
||||
|
||||
cres =
|
||||
kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb.");
|
||||
if (strcmp(cres,"Mary Had A Little Lamb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with AppendStrings "
|
||||
<< "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
|
||||
cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb.");
|
||||
if (strcmp(cres, "Mary Had A Little Lamb.")) {
|
||||
std::cerr << "Problem with AppendStrings "
|
||||
<< "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres;
|
||||
}
|
||||
delete[] cres;
|
||||
|
||||
if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.",'a') != 3)
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with CountChar "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.", 'a') != 3) {
|
||||
std::cerr << "Problem with CountChar "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
cres =
|
||||
kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou");
|
||||
if (strcmp(cres,"Mry Hd A Lttl Lmb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveChars "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou");
|
||||
if (strcmp(cres, "Mry Hd A Lttl Lmb.")) {
|
||||
std::cerr << "Problem with RemoveChars "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres;
|
||||
}
|
||||
delete[] cres;
|
||||
|
||||
cres =
|
||||
kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
|
||||
if (strcmp(cres,"A"))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with RemoveCharsButUpperHex "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
|
||||
if (strcmp(cres, "A")) {
|
||||
std::cerr << "Problem with RemoveCharsButUpperHex "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres;
|
||||
}
|
||||
delete[] cres;
|
||||
|
||||
char *cres2 = new char [strlen("Mary Had A Little Lamb.")+1];
|
||||
strcpy(cres2,"Mary Had A Little Lamb.");
|
||||
kwsys::SystemTools::ReplaceChars(cres2,"aeiou",'X');
|
||||
if (strcmp(cres2,"MXry HXd A LXttlX LXmb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ReplaceChars "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
char* cres2 = new char[strlen("Mary Had A Little Lamb.") + 1];
|
||||
strcpy(cres2, "Mary Had A Little Lamb.");
|
||||
kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X');
|
||||
if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) {
|
||||
std::cerr << "Problem with ReplaceChars "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres2;
|
||||
}
|
||||
delete[] cres2;
|
||||
|
||||
if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.",
|
||||
"Mary "))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with StringStartsWith "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
"Mary ")) {
|
||||
std::cerr << "Problem with StringStartsWith "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
|
||||
" Lamb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with StringEndsWith "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
" Lamb.")) {
|
||||
std::cerr << "Problem with StringEndsWith "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
|
||||
if (strcmp(cres,"Mary Had A Little Lamb."))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with DuplicateString "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
if (strcmp(cres, "Mary Had A Little Lamb.")) {
|
||||
std::cerr << "Problem with DuplicateString "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
delete [] cres;
|
||||
}
|
||||
delete[] cres;
|
||||
|
||||
test = "Mary Had A Little Lamb.";
|
||||
if (kwsys::SystemTools::CropString(test,13) !=
|
||||
"Mary ...Lamb.")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with CropString "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
if (kwsys::SystemTools::CropString(test, 13) != "Mary ...Lamb.") {
|
||||
std::cerr << "Problem with CropString "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> lines;
|
||||
kwsys::SystemTools::Split("Mary Had A Little Lamb.",lines,' ');
|
||||
if (lines[0] != "Mary" || lines[1] != "Had" ||
|
||||
lines[2] != "A" || lines[3] != "Little" || lines[4] != "Lamb.")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with Split "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
kwsys::SystemTools::Split("Mary Had A Little Lamb.", lines, ' ');
|
||||
if (lines[0] != "Mary" || lines[1] != "Had" || lines[2] != "A" ||
|
||||
lines[3] != "Little" || lines[4] != "Lamb.") {
|
||||
std::cerr << "Problem with Split "
|
||||
<< "\"Mary Had A Little Lamb.\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath
|
||||
("L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
|
||||
L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
|
||||
"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
|
||||
L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath
|
||||
("L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
|
||||
"L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath
|
||||
("\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
|
||||
L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
|
||||
"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
|
||||
L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath
|
||||
("//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
|
||||
"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") !=
|
||||
L"//")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"//\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") != L"//") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"//\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
|
||||
L"\\\\.\\")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\\""
|
||||
<< std::endl;
|
||||
L"\\\\.\\") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
|
||||
L"\\\\.\\X")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X\""
|
||||
<< std::endl;
|
||||
L"\\\\.\\X") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
|
||||
L"\\\\?\\X:")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X:\""
|
||||
<< std::endl;
|
||||
L"\\\\?\\X:") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X:\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
|
||||
L"\\\\?\\X:\\")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X:\\\""
|
||||
<< std::endl;
|
||||
L"\\\\?\\X:\\") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"\\\\.\\X:\\\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
|
||||
L"\\\\.\\NUL")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"NUL\""
|
||||
<< std::endl;
|
||||
L"\\\\.\\NUL") {
|
||||
std::cerr << "Problem with ConvertToWindowsExtendedPath "
|
||||
<< "\"NUL\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsOutputPath
|
||||
("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsOutputPath "
|
||||
<< "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsOutputPath(
|
||||
"L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {
|
||||
std::cerr << "Problem with ConvertToWindowsOutputPath "
|
||||
<< "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToWindowsOutputPath
|
||||
("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToWindowsOutputPath "
|
||||
<< "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToWindowsOutputPath(
|
||||
"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {
|
||||
std::cerr << "Problem with ConvertToWindowsOutputPath "
|
||||
<< "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kwsys::SystemTools::ConvertToUnixOutputPath
|
||||
("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo")
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with ConvertToUnixOutputPath "
|
||||
<< "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
|
||||
<< std::endl;
|
||||
if (kwsys::SystemTools::ConvertToUnixOutputPath(
|
||||
"//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
|
||||
"//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") {
|
||||
std::cerr << "Problem with ConvertToUnixOutputPath "
|
||||
<< "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static bool CheckPutEnv(const std::string& env, const char* name, const char* value)
|
||||
static bool CheckPutEnv(const std::string& env, const char* name,
|
||||
const char* value)
|
||||
{
|
||||
if(!kwsys::SystemTools::PutEnv(env))
|
||||
{
|
||||
std::cerr << "PutEnv(\"" << env
|
||||
<< "\") failed!" << std::endl;
|
||||
if (!kwsys::SystemTools::PutEnv(env)) {
|
||||
std::cerr << "PutEnv(\"" << env << "\") failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string v = "(null)";
|
||||
kwsys::SystemTools::GetEnv(name, v);
|
||||
if(v != value)
|
||||
{
|
||||
std::cerr << "GetEnv(\"" << name << "\") returned \""
|
||||
<< v << "\", not \"" << value << "\"!" << std::endl;
|
||||
if (v != value) {
|
||||
std::cerr << "GetEnv(\"" << name << "\") returned \"" << v << "\", not \""
|
||||
<< value << "\"!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckUnPutEnv(const char* env, const char* name)
|
||||
{
|
||||
if(!kwsys::SystemTools::UnPutEnv(env))
|
||||
{
|
||||
std::cerr << "UnPutEnv(\"" << env << "\") failed!"
|
||||
<< std::endl;
|
||||
if (!kwsys::SystemTools::UnPutEnv(env)) {
|
||||
std::cerr << "UnPutEnv(\"" << env << "\") failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string v;
|
||||
if(kwsys::SystemTools::GetEnv(name, v))
|
||||
{
|
||||
std::cerr << "GetEnv(\"" << name << "\") returned \""
|
||||
<< v << "\", not (null)!" << std::endl;
|
||||
if (kwsys::SystemTools::GetEnv(name, v)) {
|
||||
std::cerr << "GetEnv(\"" << name << "\") returned \"" << v
|
||||
<< "\", not (null)!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -933,19 +725,16 @@ static bool CheckEnvironmentOperations()
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static bool CheckRelativePath(
|
||||
const std::string& local,
|
||||
const std::string& remote,
|
||||
const std::string& expected)
|
||||
static bool CheckRelativePath(const std::string& local,
|
||||
const std::string& remote,
|
||||
const std::string& expected)
|
||||
{
|
||||
std::string result = kwsys::SystemTools::RelativePath(local, remote);
|
||||
if (!kwsys::SystemTools::ComparePath(expected, result))
|
||||
{
|
||||
std::cerr << "RelativePath(" << local << ", " << remote
|
||||
<< ") yielded " << result << " instead of " << expected << std::endl;
|
||||
if (!kwsys::SystemTools::ComparePath(expected, result)) {
|
||||
std::cerr << "RelativePath(" << local << ", " << remote << ") yielded "
|
||||
<< result << " instead of " << expected << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -955,22 +744,21 @@ static bool CheckRelativePaths()
|
||||
res &= CheckRelativePath("/usr/share", "/bin/bash", "../../bin/bash");
|
||||
res &= CheckRelativePath("/usr/./share/", "/bin/bash", "../../bin/bash");
|
||||
res &= CheckRelativePath("/usr//share/", "/bin/bash", "../../bin/bash");
|
||||
res &= CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash");
|
||||
res &=
|
||||
CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash");
|
||||
res &= CheckRelativePath("/usr/share", "/usr/share//bin", "bin");
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool CheckCollapsePath(
|
||||
const std::string& path,
|
||||
const std::string& expected)
|
||||
static bool CheckCollapsePath(const std::string& path,
|
||||
const std::string& expected)
|
||||
{
|
||||
std::string result = kwsys::SystemTools::CollapseFullPath(path);
|
||||
if (!kwsys::SystemTools::ComparePath(expected, result))
|
||||
{
|
||||
std::cerr << "CollapseFullPath(" << path
|
||||
<< ") yielded " << result << " instead of " << expected << std::endl;
|
||||
if (!kwsys::SystemTools::ComparePath(expected, result)) {
|
||||
std::cerr << "CollapseFullPath(" << path << ") yielded " << result
|
||||
<< " instead of " << expected << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -987,14 +775,12 @@ static std::string StringVectorToString(const std::vector<std::string>& vec)
|
||||
std::stringstream ss;
|
||||
ss << "vector(";
|
||||
for (std::vector<std::string>::const_iterator i = vec.begin();
|
||||
i != vec.end(); ++i)
|
||||
{
|
||||
if (i != vec.begin())
|
||||
{
|
||||
i != vec.end(); ++i) {
|
||||
if (i != vec.begin()) {
|
||||
ss << ", ";
|
||||
}
|
||||
ss << *i;
|
||||
}
|
||||
ss << *i;
|
||||
}
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
@@ -1028,15 +814,13 @@ static bool CheckGetPath()
|
||||
std::vector<std::string> pathes = originalPathes;
|
||||
kwsys::SystemTools::GetPath(pathes, envName);
|
||||
|
||||
if (pathes != expectedPathes)
|
||||
{
|
||||
std::cerr <<
|
||||
"GetPath(" << StringVectorToString(originalPathes) <<
|
||||
", " << envName << ") yielded " << StringVectorToString(pathes) <<
|
||||
" instead of " << StringVectorToString(expectedPathes) <<
|
||||
std::endl;
|
||||
if (pathes != expectedPathes) {
|
||||
std::cerr << "GetPath(" << StringVectorToString(originalPathes) << ", "
|
||||
<< envName << ") yielded " << StringVectorToString(pathes)
|
||||
<< " instead of " << StringVectorToString(expectedPathes)
|
||||
<< std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
res &= CheckUnPutEnv(envName, envName);
|
||||
return res;
|
||||
@@ -1046,64 +830,54 @@ static bool CheckFind()
|
||||
{
|
||||
bool res = true;
|
||||
const std::string testFindFileName("testFindFile.txt");
|
||||
const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/"
|
||||
+ testFindFileName);
|
||||
const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/" +
|
||||
testFindFileName);
|
||||
|
||||
if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true))
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with Touch for: "
|
||||
<< testFindFile << std::endl;
|
||||
if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true)) {
|
||||
std::cerr << "Problem with Touch for: " << testFindFile << std::endl;
|
||||
// abort here as the existence of the file only makes the test meaningful
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> searchPaths;
|
||||
searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
|
||||
if (kwsys::SystemTools::FindFile(testFindFileName,
|
||||
searchPaths, true).empty())
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FindFile without system paths for: "
|
||||
<< testFindFileName << std::endl;
|
||||
if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true)
|
||||
.empty()) {
|
||||
std::cerr << "Problem with FindFile without system paths for: "
|
||||
<< testFindFileName << std::endl;
|
||||
res = false;
|
||||
}
|
||||
if (kwsys::SystemTools::FindFile(testFindFileName,
|
||||
searchPaths, false).empty())
|
||||
{
|
||||
std::cerr
|
||||
<< "Problem with FindFile with system paths for: "
|
||||
<< testFindFileName << std::endl;
|
||||
}
|
||||
if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, false)
|
||||
.empty()) {
|
||||
std::cerr << "Problem with FindFile with system paths for: "
|
||||
<< testFindFileName << std::endl;
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int testSystemTools(int, char*[])
|
||||
int testSystemTools(int, char* [])
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
int cc;
|
||||
for ( cc = 0; toUnixPaths[cc][0]; cc ++ )
|
||||
{
|
||||
for (cc = 0; toUnixPaths[cc][0]; cc++) {
|
||||
res &= CheckConvertToUnixSlashes(toUnixPaths[cc][0], toUnixPaths[cc][1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Special check for ~
|
||||
std::string output;
|
||||
if(kwsys::SystemTools::GetEnv("HOME", output))
|
||||
{
|
||||
if (kwsys::SystemTools::GetEnv("HOME", output)) {
|
||||
output += "/foo bar/lala";
|
||||
res &= CheckConvertToUnixSlashes("~/foo bar/lala", output);
|
||||
}
|
||||
}
|
||||
|
||||
for (cc = 0; checkEscapeChars[cc][0]; cc ++ )
|
||||
{
|
||||
for (cc = 0; checkEscapeChars[cc][0]; cc++) {
|
||||
res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
|
||||
*checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
|
||||
}
|
||||
}
|
||||
|
||||
res &= CheckFileOperations();
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
|
||||
#ifndef @KWSYS_NAMESPACE@_testSystemtools_h
|
||||
#define @KWSYS_NAMESPACE@_testSystemtools_h
|
||||
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
/* 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(Terminal.h)
|
||||
|
||||
/* Work-around CMake dependency scanning limitation. This must
|
||||
duplicate the above list of headers. */
|
||||
#if 0
|
||||
# include "Terminal.h.in"
|
||||
#include "Terminal.h.in"
|
||||
#endif
|
||||
|
||||
int testTerminal(int argc, char* argv[])
|
||||
@@ -23,8 +14,8 @@ int testTerminal(int argc, char* argv[])
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
kwsysTerminal_cfprintf(kwsysTerminal_Color_ForegroundYellow |
|
||||
kwsysTerminal_Color_BackgroundBlue |
|
||||
kwsysTerminal_Color_AssumeTTY,
|
||||
kwsysTerminal_Color_BackgroundBlue |
|
||||
kwsysTerminal_Color_AssumeTTY,
|
||||
stdout, "Hello %s!", "World");
|
||||
fprintf(stdout, "\n");
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user