Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Imported upstream 1.9.114

Signed-off-by: Stefan Naewe <stefan.naewe@atlas-elektronik.com>
  • Loading branch information...
commit 2a93f2c372071594b26b54bedf5c64002c672e37 1 parent 3369df6
Stefan Naewe authored
40 CHANGES.txt
View
@@ -18,6 +18,46 @@ STLSoft - Changes
============================================================================
+Changes for 1.9.114 (4th June 2012)
+
+Summary:
+========
+
+ * added unixstl::filesystem_traits::is_socket(char_type const*) method
+ * added unixstl::filesystem_traits::is_link(char_type const*) method
+ * added unixstl::filesystem_traits::is_socket(stat_data_type const*) method
+ * added unixstl::filesystem_traits::find_next_path_name_separator() method
+ * added unixstl::filesystem_traits::find_last_path_name_separator() method
+ * unixstl::filesystem_traits::get_full_path_name() now canonicalises '.'/'..'-trailing paths
+ * unixstl::readdir_sequence.hpp now includes directory name in thrown exception
+
+Changes:
+========
+
+ UNIXSTL:
+ ========
+
+ ~ unixstl/filesystem/filesystem_traits.hpp:
+ ~ canonicalised '.' and '..'-trailing paths
+ ~ refactored get_full_path defect() logic
+ ~ fixed defect whereby too much of a source string was being copied over into buffer (leading to a seg-fault on UNIX)
+ + added is_socket(char_type const*)
+ + added is_link(char_type const*)
+ + added is_socket(stat_data_type const*)
+ + added find_next_path_name_separator()
+ + added find_last_path_name_separator()
+
+ ~ unixstl/filesystem/glob_sequence.hpp:
+ ~ refactored way in which patterns and directories are pre-parsed
+
+ ~ unixstl/filesystem/readdir_sequence.hpp:
+ + readdir_sequence_exception now has a Directory property
+ + now includes directory name in thrown exception
+ ~ minor compatibility fixes
+
+
+============================================================================
+
Changes for 1.9.113 (4th June 2012)
Summary:
12 HISTORY.txt
View
@@ -7,6 +7,18 @@ STLSoft - History
============================================================================
+4th June 2012 - 1.9.114 released
+--------------------------------
+
+ * added unixstl::filesystem_traits::is_socket(char_type const*) method
+ * added unixstl::filesystem_traits::is_link(char_type const*) method
+ * added unixstl::filesystem_traits::is_socket(stat_data_type const*) method
+ * added unixstl::filesystem_traits::find_next_path_name_separator() method
+ * added unixstl::filesystem_traits::find_last_path_name_separator() method
+ * unixstl::filesystem_traits::get_full_path_name() now canonicalises '.'/'..'-trailing paths
+ * unixstl::readdir_sequence.hpp now includes directory name in thrown exception
+
+
4th June 2012 - 1.9.113 released
--------------------------------
12 INSTALL.txt
View
@@ -2,7 +2,7 @@
STLSoft - Install
; Created: 29th March 2002
-; Updated: 3rd June 2012
+; Updated: 4th June 2012
============================================================================
@@ -11,16 +11,16 @@ STLSoft - Install
It is recommended that you define an STLSOFT environment variable.
For example, if you're using UNIX and you install
- to /usr/local/stlsoft/stlsoft-1.9.113 then you should set the environment
- variable STLSOFT to /usr/local/stlsoft/stlsoft-1.9.113 in which case the
+ to /usr/local/stlsoft/stlsoft-1.9.114 then you should set the environment
+ variable STLSOFT to /usr/local/stlsoft/stlsoft-1.9.114 in which case the
file stlsoft/stlsoft.h will be located in
$STLSOFT/include/stlsoft/stlsoft.h
Conversely, if you're using Windows and you intall
- to C:\3pty\STLSoft\stlsoft-1.9.113 then you should set the environment
- variable STLSoft to C:\3pty\STLSoft\stlsoft-1.9.113 in which case the
+ to C:\3pty\STLSoft\stlsoft-1.9.114 then you should set the environment
+ variable STLSoft to C:\3pty\STLSoft\stlsoft-1.9.114 in which case the
file stlsoft/stlsoft.h will be located in
- C:\3pty\STLSoft\stlsoft-1.9.113\stlsoft\stlsoft.h
+ C:\3pty\STLSoft\stlsoft-1.9.114\stlsoft\stlsoft.h
The makefiles / project files of several other open-source projects expect
this symbol, including:
2  NEWS.txt
View
@@ -9,6 +9,8 @@ STLSoft - News
News:
+ 4th June 2012 - Release of STLSoft 1.9.114
+
4th June 2012 - Release of STLSoft 1.9.113
7th February 2012 - Release of STLSoft 1.9.112
11 include/stlsoft/stlsoft.h
View
@@ -6,7 +6,7 @@
* types.
*
* Created: 15th January 2002
- * Updated: 3rd June 2012
+ * Updated: 4th June 2012
*
* Home: http://stlsoft.org/
*
@@ -54,8 +54,8 @@
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define STLSOFT_VER_STLSOFT_H_STLSOFT_MAJOR 3
# define STLSOFT_VER_STLSOFT_H_STLSOFT_MINOR 25
-# define STLSOFT_VER_STLSOFT_H_STLSOFT_REVISION 1
-# define STLSOFT_VER_STLSOFT_H_STLSOFT_EDIT 425
+# define STLSOFT_VER_STLSOFT_H_STLSOFT_REVISION 2
+# define STLSOFT_VER_STLSOFT_H_STLSOFT_EDIT 426
#else /* ? STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* # include "./internal/doxygen_defs.h" */
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
@@ -276,12 +276,13 @@
# define _STLSOFT_VER_1_9_111 0x01096fff /*!< Version 1.9.111 (30th November 2011) */
# define _STLSOFT_VER_1_9_112 0x010970ff /*!< Version 1.9.112 (7th February 2012) */
# define _STLSOFT_VER_1_9_113 0x010971ff /*!< Version 1.9.113 (4th June 2012) */
+# define _STLSOFT_VER_1_9_114 0x010972ff /*!< Version 1.9.114 (4th June 2012) */
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
#define _STLSOFT_VER_MAJOR 1
#define _STLSOFT_VER_MINOR 9
-#define _STLSOFT_VER_REVISION 113
-#define _STLSOFT_VER _STLSOFT_VER_1_9_113
+#define _STLSOFT_VER_REVISION 114
+#define _STLSOFT_VER _STLSOFT_VER_1_9_114
/* /////////////////////////////////////////////////////////////////////////
* Basic macros
398 include/unixstl/filesystem/filesystem_traits.hpp
View
@@ -5,7 +5,7 @@
* Unicode specialisations thereof.
*
* Created: 15th November 2002
- * Updated: 20th May 2012
+ * Updated: 4th June 2012
*
* Thanks: To Sergey Nikulov, for spotting a preprocessor typo that
* broke GCC -pedantic; to Michal Makowski and Zar Eindl for
@@ -57,9 +57,9 @@
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 4
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 8
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 7
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 126
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 10
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 3
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 132
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
@@ -254,6 +254,12 @@ struct filesystem_traits
/// \see \link #path_name_separator path_name_separator() \endlink
static bool_type has_dir_end(char_type const* dir);
+ /// Returns pointer to the next path_name_separator, or \c NULL if none found.
+ static char_type const* find_next_path_name_separator(char_type const* path);
+
+ /// Returns pointer to the last path_name_separator, or \c NULL if none found.
+ static char_type const* find_last_path_name_separator(char_type const* path);
+
/// \brief Returns \c true if dir is \c "." or \c ".."
static bool_type is_dots(char_type const* dir);
/// \brief Returns \c true if path is rooted
@@ -366,6 +372,12 @@ struct filesystem_traits
static bool_type is_file(char_type const* path);
/// \brief Returns whether the given path represents a directory
static bool_type is_directory(char_type const* path);
+#ifndef _WIN32
+ /// \brief Returns whether the given path represents a socket
+ static bool_type is_socket(char_type const* path);
+#endif /* OS */
+ /// \brief Returns whether the given path represents a link
+ static bool_type is_link(char_type const* path);
/// \brief Gets the information for a particular file system entry
static bool_type stat(char_type const* path, stat_data_type* stat_data);
@@ -378,6 +390,10 @@ struct filesystem_traits
static bool_type is_file(stat_data_type const* stat_data);
/// \brief Returns whether the given stat info represents a directory
static bool_type is_directory(stat_data_type const* stat_data);
+#ifndef _WIN32
+ /// \brief Returns whether the given stat info represents a socket
+ static bool_type is_socket(stat_data_type const* stat_data);
+#endif /* OS */
/// \brief Returns whether the given stat info represents a link
static bool_type is_link(stat_data_type const* stat_data);
@@ -451,7 +467,11 @@ struct filesystem_traits_util_
#else /* ? _WIN32 */
typedef mode_t mode_type;
#endif /* _WIN32 */
+#if 1
protected:
+#else /* ? 0 */
+public:
+#endif /* 0 */
static bool_type is_file_type_(
stat_data_type const* stat_data
, mode_type typeModeBits
@@ -480,6 +500,9 @@ struct filesystem_traits;
STLSOFT_TEMPLATE_SPECIALISATION
struct filesystem_traits<us_char_a_t>
: public system_traits<us_char_a_t>
+#if 0
+ , protected filesystem_traits_util_
+#endif /* 0 */
{
public:
typedef us_char_a_t char_type;
@@ -597,6 +620,54 @@ struct filesystem_traits<us_char_a_t>
return (0 < len) && is_path_name_separator(dir[len - 1]);
}
+ static
+ char_type const*
+ find_next_path_name_separator(char_type const* path)
+ {
+ char_type* pFile = str_chr(path, path_name_separator());
+#if defined(_WIN32)
+ char_type* pFile2 = str_chr(path, '\\');
+
+ if(NULL == pFile)
+ {
+ pFile = pFile2;
+ }
+ else if(NULL != pFile2)
+ {
+ if(pFile2 < pFile)
+ {
+ pFile = pFile2;
+ }
+ }
+#endif /* _WIN32 */
+
+ return pFile;
+ }
+
+ static
+ char_type const*
+ find_last_path_name_separator(char_type const* path)
+ {
+ char_type* pFile = str_rchr(path, path_name_separator());
+#if defined(_WIN32)
+ char_type* pFile2 = str_rchr(path, '\\');
+
+ if(NULL == pFile)
+ {
+ pFile = pFile2;
+ }
+ else if(NULL != pFile2)
+ {
+ if(pFile2 > pFile)
+ {
+ pFile = pFile2;
+ }
+ }
+#endif /* _WIN32 */
+
+ return pFile;
+ }
+
static bool_type is_dots(char_type const* dir)
{
UNIXSTL_ASSERT(NULL != dir);
@@ -874,8 +945,81 @@ struct filesystem_traits<us_char_a_t>
}
private:
- static size_type get_full_path_name_impl2(char_type const* fileName, us_size_t len, char_type* buffer, size_type cchBuffer)
+ // TODO: promote this to public
+ static
+ size_type
+ get_root_len_(
+ char_type const* path
+ , size_type len
+ )
+ {
+ if(0 == len)
+ {
+ return 0;
+ }
+
+#ifdef _WIN32
+ // If it's really on Windows, then we need to check for drive designator
+ if( iswalpha(path[0]) &&
+ ':' == path[1] &&
+ is_path_name_separator(path[2]))
+ {
+ return 3;
+ }
+
+ // If it's really on Windows, then we need to skip the drive, if present
+ if( '\\' == path[0] &&
+ '\\' == path[1])
+ {
+ char_type const* slash2 = find_next_path_name_separator(path + 2);
+
+ if(NULL == slash2)
+ {
+#if 0
+ SetLastError(ERROR_INVALID_ARGUMENT);
+#endif /* 0 */
+
+ return 0;
+ }
+ else
+ {
+ return 1 + (slash2 - path);
+ }
+ }
+
+#endif /* _WIN32 */
+
+ return is_path_name_separator(path[0]) ? 1 : 0;
+ }
+
+ static
+ size_type
+ get_root_len_(
+ char_type const* path
+ )
{
+ UNIXSTL_ASSERT(NULL != path);
+
+ size_type const len = str_len(path);
+
+ return get_root_len_(path, len);
+ }
+
+ static
+ size_type
+ get_full_path_name_impl2(
+ char_type const* fileName
+ , us_size_t const len
+ , char_type* buffer
+ , size_type cchBuffer
+ )
+ {
+ if( NULL != buffer &&
+ 0 == cchBuffer)
+ {
+ return 0;
+ }
+
// The next thing to so is determine whether the path is absolute, in
// which case we'll just copy it into the buffer
if(is_path_rooted(fileName))
@@ -883,18 +1027,21 @@ struct filesystem_traits<us_char_a_t>
// Given path is absolute, so simply copy into buffer
if(NULL == buffer)
{
- len = len;
+ return len;
}
- else if(cchBuffer < len)
+ else if(cchBuffer < len + 1)
{
char_copy(&buffer[0], fileName, cchBuffer);
- len = cchBuffer;
+
+ return cchBuffer;
}
else
{
// Given buffer is large enough, so copy
char_copy(&buffer[0], fileName, len);
buffer[len] = '\0';
+
+ return len;
}
}
else
@@ -908,11 +1055,6 @@ struct filesystem_traits<us_char_a_t>
return 0;
}
- else if(NULL != buffer &&
- 0 == cchBuffer)
- {
- return 0;
- }
else
{
size_type lenDir = get_current_directory(&directory[0], directory.size());
@@ -920,63 +1062,127 @@ struct filesystem_traits<us_char_a_t>
if(0 == lenDir)
{
// The call failed, so indicate that to caller
- len = 0;
+ return 0;
}
else
{
- if( 1 == len &&
- '.' == fileName[0])
+ if( '.' == fileName[0] &&
+ ( 1 == len ||
+ ( 2 == len &&
+ '.' == fileName[1])))
{
- if(NULL == buffer)
+ if(1 == len)
{
- len = lenDir;
+ // '.'
+
+ if(NULL == buffer)
+ {
+ return lenDir;
+ }
}
else
+ if(2 == len)
{
- if(cchBuffer < lenDir)
+ // '..'
+
+ size_t const rootLen = get_root_len_(directory.data(), lenDir);
+
+ // Remove trailing slash, if any
+ if( lenDir > rootLen &&
+ has_dir_end(directory.data() + (lenDir - 1)))
{
- char_copy(&buffer[0], directory.data(), cchBuffer);
- len = cchBuffer;
+ remove_dir_end(directory.data() + (lenDir - 1));
+ --lenDir;
}
- else
+
+ if(lenDir > rootLen)
{
- // Given buffer is large enough, so copy
- char_copy(buffer, directory.data(), lenDir);
- buffer[lenDir] = '\0';
- len = lenDir;
+ char_type* const lastSlash = const_cast<char_type*>(find_last_path_name_separator(directory.data() + rootLen));
+
+ if(NULL != lastSlash)
+ {
+ size_t const newLen = lastSlash - directory.data();
+
+ directory[newLen] = '\0';
+ lenDir = newLen;
+ }
+ else
+ {
+ directory[rootLen] = '\0';
+ lenDir = rootLen;
+ }
+ }
+
+ if(NULL == buffer)
+ {
+ return lenDir;
}
}
+
+ if(cchBuffer < lenDir + 1)
+ {
+ char_copy(&buffer[0], directory.data(), cchBuffer);
+
+ return cchBuffer;
+ }
+ else
+ {
+ // Given buffer is large enough, so copy
+ char_copy(buffer, directory.data(), lenDir);
+ buffer[lenDir] = '\0';
+
+ return lenDir;
+ }
+
+// For some reason OS-X's GCC needs this : it's confused.
+#if defined(STLSOFT_COMPILER_IS_GCC) && \
+ STLSOFT_GCC_VER >= 40200 && \
+ STLSOFT_GCC_VER < 40300
+UNIXSTL_ASSERT(0); // should never get here
+return 0;
+#endif
}
else
{
- if(!has_dir_end(&directory[0] + (lenDir - 1)))
- {
- ++lenDir;
- }
- ensure_dir_end(&directory[0]);
+ lenDir += str_len(ensure_dir_end(&directory[0] + (lenDir - 1))) - 1;
- len += lenDir;
+ size_type const required = len + lenDir;
- if(NULL != buffer)
+ if(NULL == buffer)
{
- char_copy(&buffer[0], directory.data(), cchBuffer);
-
- if(cchBuffer > lenDir)
+ return required;
+ }
+ else
+ {
+ if(cchBuffer < lenDir + 1)
{
- char_copy(&buffer[0] + lenDir, fileName, cchBuffer - lenDir);
- }
+ char_copy(&buffer[0], directory.data(), cchBuffer);
- if(cchBuffer < len)
+ return cchBuffer;
+ }
+ else
{
- len = cchBuffer;
+ char_copy(&buffer[0], directory.data(), lenDir);
+
+ if(cchBuffer < required + 1)
+ {
+ char_copy(&buffer[0] + lenDir, fileName, cchBuffer - lenDir);
+
+ return cchBuffer;
+ }
+ else
+ {
+ char_copy(&buffer[0] + lenDir, fileName, len);
+ buffer[lenDir + len] = '\0';
+
+ return required;
+ }
}
}
}
}
}
}
-
- return len;
}
static size_type get_full_path_name_impl(char_type const* fileName, us_size_t len, char_type* buffer, size_type cchBuffer)
@@ -1039,22 +1245,7 @@ struct filesystem_traits<us_char_a_t>
if(r == cchRequired)
{
// Now search for the file separator
- char_type* pFile = str_rchr(buffer, path_name_separator());
-#if defined(_WIN32)
- char_type* pFile2 = str_rchr(buffer, '\\');
-
- if(NULL == pFile)
- {
- pFile = pFile2;
- }
- else if(NULL != pFile2)
- {
- if(pFile2 > pFile)
- {
- pFile = pFile2;
- }
- }
-#endif /* _WIN32 */
+ char_type* pFile = const_cast<char_type*>(find_last_path_name_separator(buffer));
if(NULL != (*ppFile = pFile))
{
@@ -1235,6 +1426,24 @@ struct filesystem_traits<us_char_a_t>
return class_type::stat(path, &sd) && S_IFDIR == (sd.st_mode & S_IFMT);
}
+#ifndef _WIN32
+ static bool_type is_socket(char_type const* path)
+ {
+ stat_data_type sd;
+
+ return class_type::stat(path, &sd) && S_IFSOCK == (sd.st_mode & S_IFMT);
+ }
+#endif /* OS */
+ static bool_type is_link(char_type const* path)
+ {
+#ifdef _WIN32
+ return false;
+#else /* ? _WIN32 */
+ stat_data_type sd;
+
+ return class_type::lstat(path, &sd) && S_IFLNK == (sd.st_mode & S_IFMT);
+#endif /* _WIN32 */
+ }
static bool_type stat(char_type const* path, stat_data_type* stat_data)
{
@@ -1303,12 +1512,30 @@ struct filesystem_traits<us_char_a_t>
static bool_type is_file(stat_data_type const* stat_data)
{
+#if 1
return S_IFREG == (stat_data->st_mode & S_IFMT);
+#else
+ return filesystem_traits_util_::is_file_type_(stat_data, S_IFREG);
+#endif
}
static bool_type is_directory(stat_data_type const* stat_data)
{
+#if 1
return S_IFDIR == (stat_data->st_mode & S_IFMT);
+#else /* ? 0 */
+ return filesystem_traits_util_::is_file_type_(stat_data, S_IFDIR);
+#endif /* 0 */
+ }
+#ifndef _WIN32
+ static bool_type is_socket(stat_data_type const* stat_data)
+ {
+#if 1
+ return S_IFSOCK == (stat_data->st_mode & S_IFMT);
+#else /* ? 0 */
+ return filesystem_traits_util_::is_file_type_(stat_data, S_IFSOCK);
+#endif /* 0 */
}
+#endif /* OS */
static bool_type is_link(stat_data_type const* stat_data)
{
#ifdef _WIN32
@@ -1316,7 +1543,11 @@ struct filesystem_traits<us_char_a_t>
return false;
#else /* ? _WIN32 */
+#if 1
return S_IFLNK == (stat_data->st_mode & S_IFMT);
+#else /* ? 0 */
+ return filesystem_traits_util_::is_file_type_(stat_data, S_IFLNK);
+#endif /* 0 */
#endif /* _WIN32 */
}
@@ -1462,6 +1693,9 @@ struct filesystem_traits<us_char_a_t>
STLSOFT_TEMPLATE_SPECIALISATION
struct filesystem_traits<us_char_w_t>
: public system_traits<us_char_w_t>
+#if 0
+ , protected filesystem_traits_util_
+#endif /* 0 */
{
public:
typedef us_char_w_t char_type;
@@ -1561,6 +1795,54 @@ struct filesystem_traits<us_char_w_t>
return (0 < len) && is_path_name_separator(dir[len - 1]);
}
+ static
+ char_type const*
+ find_next_path_name_separator(char_type const* path)
+ {
+ char_type* pFile = str_chr(path, path_name_separator());
+#if defined(_WIN32)
+ char_type* pFile2 = str_chr(path, L'\\');
+
+ if(NULL == pFile)
+ {
+ pFile = pFile2;
+ }
+ else if(NULL != pFile2)
+ {
+ if(pFile2 < pFile)
+ {
+ pFile = pFile2;
+ }
+ }
+#endif /* _WIN32 */
+
+ return pFile;
+ }
+
+ static
+ char_type const*
+ find_last_path_name_separator(char_type const* path)
+ {
+ char_type* pFile = str_rchr(path, path_name_separator());
+#if defined(_WIN32)
+ char_type* pFile2 = str_rchr(path, L'\\');
+
+ if(NULL == pFile)
+ {
+ pFile = pFile2;
+ }
+ else if(NULL != pFile2)
+ {
+ if(pFile2 > pFile)
+ {
+ pFile = pFile2;
+ }
+ }
+#endif /* _WIN32 */
+
+ return pFile;
+ }
+
static bool_type is_dots(char_type const* dir)
{
UNIXSTL_ASSERT(NULL != dir);
177 include/unixstl/filesystem/glob_sequence.hpp
View
@@ -4,7 +4,7 @@
* Purpose: glob_sequence class.
*
* Created: 15th January 2002
- * Updated: 27th May 2012
+ * Updated: 4th June 2012
*
* Thanks: To Carlos Santander Bernal for helping with Mac compatibility.
* To Nevin Liber for pressing upon me the need to lead by
@@ -54,8 +54,8 @@
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MAJOR 5
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MINOR 2
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_REVISION 3
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_EDIT 157
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_REVISION 5
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_EDIT 159
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
@@ -370,7 +370,7 @@ class glob_sequence
, files = 0x0020 /*!< \brief Causes the search to include files */
, noSort = 0x0100 /*!< \brief Does not sort entries. Corresponds to GLOB_NOSORT. */
, markDirs = 0x0200 /*!< \brief Mark directories with a trailing path name separator. Corresponds to GLOB_MARK. */
- , absolutePath = 0x0400 /*!< \brief Return all entries in absolute format */
+ , absolutePath = 0x0400 /*!< \brief Return all entries in absolute format. Ignored when a dots directory is specified as the pattern. Note, absolute paths may not always be in canonical form, e.g. '/user/me/.' if specify ('/user/me', '.', absolutePath), in which case the caller is responsible for obtaining canonical form. */
, breakOnError = 0x0800 /*!< \brief Causes processing to stop on the first filesystem error. Corresponds to GLOB_ERR. */
, noEscape = 0x1000 /*!< \brief Treats backslashes literally. Corresponds to GLOB_NOESCAPE. */
@@ -595,7 +595,17 @@ class glob_sequence
static us_bool_t is_dots_maybe_slashed_(char_type const* s, us_bool_t* bTwoDots);
// Calls glob() and process the results
+ //
+ // init_glob_() - handles any directory and/or pattern (where the pattern may contain rel/abs dir)
+ // init_glob_1_() - splits combined path into directory+pattern (which are passed to init_glob_2_())
+ // init_glob_2_() - handles receives properly split directory+pattern (and does test in order to call init_glob_3_())
+ // init_glob_3_() - handles full pattern, with bool indicating whether pattern contains wildcard at leaf
us_size_t init_glob_(char_type const* directory, char_type const* pattern);
+ us_size_t init_glob_1_(size_type bufferSize, char_type* combinedPath);
+ us_size_t init_glob_2_(char_type const* patternDir, char_type const* pattern0);
+ us_size_t init_glob_3_(char_type const* pattern, bool isPattern0Wild);
+
+
/// @}
/// \name Members
@@ -677,7 +687,7 @@ inline glob_sequence::glob_sequence(char_type const* directory, char_type const*
, m_buffer(1)
{
- m_cItems = init_glob_(NULL, pattern);
+ m_cItems = init_glob_(directory, pattern);
UNIXSTL_ASSERT(is_valid());
}
@@ -879,59 +889,142 @@ inline us_size_t glob_sequence::init_glob_(glob_sequence::char_type const* direc
{
UNIXSTL_MESSAGE_ASSERT("Null pattern given to glob_sequence", NULL != pattern);
- static char_type const s_wildChars[] = { '?', '*', '\0' };
-
- us_bool_t const isPatternWild = (NULL != traits_type::str_pbrk(pattern, s_wildChars));
-
- us_int_t glob_flags = 0;
- basic_file_path_buffer<char_type> scratch_; // Scratch buffer for directory / pattern
+ char_type const* lastSlash = traits_type::find_last_path_name_separator(pattern);
-#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
- if(0 == scratch_.size())
+ if(NULL == lastSlash)
{
- m_base = NULL;
+ // already properly separated
- return 0;
+ return init_glob_2_(directory, pattern);
}
-#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
-
- if( NULL == directory &&
- absolutePath == (m_flags & absolutePath))
+ else
{
- static const char_type s_thisDir[] = { '.', '\0' };
+ if(traits_type::is_path_rooted(pattern))
+ {
+ directory = NULL;
+ }
+
+ basic_file_path_buffer<char_type> scratch_; // Scratch buffer for directory + pattern
+
+ size_type dirLen = (NULL == directory) ? 0u : traits_type::str_len(directory);
+ size_type patLen = traits_type::str_len(pattern);
+
+ if(0 != dirLen)
+ {
+ traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
+ scratch_[dirLen] = '\0';
+ dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;
+ }
- directory = s_thisDir;
+ traits_type::char_copy(&scratch_[0] + dirLen, pattern, patLen);
+ scratch_[dirLen + patLen] = '\0';
+
+ return init_glob_1_(scratch_.size(), scratch_.data());
}
+}
+
+inline us_size_t glob_sequence::init_glob_1_(size_type bufferSize, char_type* combinedPath)
+{
+ char_type const* const lastSlash = traits_type::find_last_path_name_separator(combinedPath);
+
+ UNIXSTL_ASSERT(NULL != lastSlash);
+
+ combinedPath[lastSlash - combinedPath] = '\0';
+
+ char_type const* directory = combinedPath;
+ char_type const* pattern = lastSlash + 1;
+
+ return init_glob_2_(directory, pattern);
+}
+
+inline us_size_t glob_sequence::init_glob_2_(char_type const* directory, char_type const* pattern0)
+{
+ // Preconditions:
+ //
+ // - pattern must not be NULL
+ // - pattern must not contain a path-name separator
+ UNIXSTL_ASSERT(NULL != pattern0);
+ UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '/'));
+#ifdef _WIN32
+ UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '\\'));
+#endif /* _WIN32 */
+
+ static char_type const s_wildChars[] = { '?', '*', '\0' };
+
+ us_bool_t const isPattern0Wild = (NULL != traits_type::str_pbrk(pattern0, s_wildChars));
- // If a directory is given, then ...
if( NULL != directory &&
- '\0' != *directory)
+ '\0' != directory[0])
{
- us_size_t dirLen;
-
- // ... optionally turn it into an absolute directory, ...
- if(absolutePath == (m_flags & absolutePath))
+ if( absolutePath == (m_flags & absolutePath) &&
+ !traits_type::is_path_rooted(directory))
{
- dirLen = traits_type::get_full_path_name(directory, scratch_.size(), &scratch_[0]);
+ us_bool_t const isPatternDirWild = (NULL != traits_type::str_pbrk(directory, s_wildChars));
+
+ if(isPatternDirWild)
+ {
+ errno = EINVAL;
+
+ m_base = NULL;
+
+ return 0;
+ }
+ else
+ {
+ basic_file_path_buffer<char_type> scratch2_; // Scratch buffer for absolute path
+
+ size_type absLen = traits_type::get_full_path_name(directory, scratch2_.size(), &scratch2_[0]);
+
+ if(0 == absLen)
+ {
+ m_base = NULL;
+
+ return 0;
+ }
+ else
+ {
+ return init_glob_2_(scratch2_.data(), pattern0);
+ }
+ }
}
else
{
- dirLen = traits_type::str_len(directory);
+ basic_file_path_buffer<char_type> scratch_; // Scratch buffer for directory / pattern
- traits_type::char_copy(&scratch_[0], directory, dirLen);
- scratch_[dirLen] = '\0';
- }
+#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
+ if(0 == scratch_.size())
+ {
+ m_base = NULL;
+
+ return 0;
+ }
+ else
+#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
+ {
+ size_type dirLen = traits_type::str_len(directory);
+ size_type patLen = traits_type::str_len(pattern0);
+
+ traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
+ scratch_[dirLen] = '\0';
- // ... ensure that it has a trailing path name-separator, and ...
- traits_type::ensure_dir_end(&scratch_[0] + (dirLen ? dirLen - 1 : 0));
+ dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;
- // ... prefix directory onto pattern.
- size_type scratchLen = traits_type::str_len(scratch_.data());
- size_type patternLen = traits_type::str_len(pattern);
- traits_type::char_copy(&scratch_[0] + scratchLen, pattern, patternLen);
- scratch_[scratchLen + patternLen] = '\0';
- pattern = scratch_.c_str();
+ traits_type::char_copy(&scratch_[0] + dirLen, pattern0, patLen);
+ scratch_[dirLen + patLen] = '\0';
+
+ return init_glob_3_(scratch_.c_str(), isPattern0Wild);
+ }
+ }
}
+ else
+ {
+ return init_glob_3_(pattern0, isPattern0Wild);
+ }
+}
+
+inline us_size_t glob_sequence::init_glob_3_(char_type const* pattern, bool isPattern0Wild)
+{
+ us_int_t glob_flags = 0;
if(m_flags & noSort)
{
@@ -1030,7 +1123,7 @@ inline us_size_t glob_sequence::init_glob_(glob_sequence::char_type const* direc
// the processing. At the end we'll call detach(), to "give it"
// to the glob_sequence instance.
- stlsoft_ns_qual(scoped_handle)<glob_t*> cleanup(&m_glob, ::globfree);
+ stlsoft_ns_qual(scoped_handle)<glob_t*> cleanup(&m_glob, ::globfree);
char_type** base = m_glob.gl_pathv;
us_size_t cItems = static_cast<us_size_t>(m_glob.gl_pathc);
@@ -1045,7 +1138,7 @@ inline us_size_t glob_sequence::init_glob_(glob_sequence::char_type const* direc
// to remove directories
//
- bool const elidingDots = isPatternWild && (0 == (m_flags & includeDots));
+ bool const elidingDots = isPattern0Wild && (0 == (m_flags & includeDots));
if( elidingDots || // 1
48 include/unixstl/filesystem/readdir_sequence.hpp
View
@@ -4,7 +4,7 @@
* Purpose: readdir_sequence class.
*
* Created: 15th January 2002
- * Updated: 20th May 2012
+ * Updated: 4th June 2012
*
* Home: http://stlsoft.org/
*
@@ -49,9 +49,9 @@
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_MAJOR 5
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_MINOR 1
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_REVISION 10
-# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_EDIT 131
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_MINOR 2
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_REVISION 1
+# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_READDIR_SEQUENCE_EDIT 133
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
@@ -150,8 +150,9 @@ class readdir_sequence_exception
/// \name Types
/// @{
public:
- typedef unix_exception parent_class_type;
- typedef readdir_sequence_exception class_type;
+ typedef unix_exception parent_class_type;
+ typedef readdir_sequence_exception class_type;
+ typedef parent_class_type::string_type string_type;
/// @}
/// \name Construction
@@ -159,7 +160,27 @@ class readdir_sequence_exception
public:
readdir_sequence_exception(us_char_a_t const* message, us_int_t erno)
: parent_class_type(message, erno)
+ , Directory()
{}
+ readdir_sequence_exception(us_char_a_t const* message, us_int_t erno, us_char_a_t const* directory)
+ : parent_class_type(message, erno)
+#if 0
+ , Directory(directory)
+#else /* ? 0 */
+ , Directory(stlsoft::c_str_ptr(directory))
+#endif /* 0 */
+ {}
+ ~readdir_sequence_exception() stlsoft_throw_0()
+ {}
+private:
+ class_type& operator =(class_type const&);
+/// @}
+
+/// \name Fields
+/// @{
+public:
+ /// The name of this field is subject to change in a future revision
+ string_type const Directory;
/// @}
};
@@ -219,6 +240,7 @@ class readdir_sequence
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
, sockets = 0x0000 /*!< CURRENTLY UNSUPPORTED : DO NOT USE! This exists for forward compatibility with STLSoft 1.10 test programs, and is subject to change in the future. A future version will support sockets, but it may not use this enumerator name. */
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
+ , typeMask = 0x0070
, fullPath = 0x0100 /*!< \brief Each file entry is presented as a full path relative to the search directory. */
, absolutePath = 0x0200 /*!< \brief The search directory is converted to an absolute path. */
};
@@ -491,8 +513,10 @@ inline /* static */ readdir_sequence::flags_type readdir_sequence::validate_flag
{
const flags_type validFlags = 0
| includeDots
+ | 0
| directories
| files
+ | 0
| fullPath
| absolutePath
| 0;
@@ -528,7 +552,7 @@ inline /* static */ readdir_sequence::string_type readdir_sequence::prepare_dire
if(0 == n)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
- STLSOFT_THROW_X(readdir_sequence_exception("Failed to enumerate directory", errno));
+ STLSOFT_THROW_X(readdir_sequence_exception("Failed to enumerate directory", errno, directory));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
traits_type::char_copy(&path[0], directory, n);
path[n] = \'0';
@@ -557,7 +581,7 @@ inline readdir_sequence::const_iterator readdir_sequence::begin() const
if(NULL == dir)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
- STLSOFT_THROW_X(readdir_sequence_exception("Failed to enumerate directory", errno));
+ STLSOFT_THROW_X(readdir_sequence_exception("Failed to enumerate directory", errno, m_directory.c_str()));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
return const_iterator();
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
@@ -699,7 +723,9 @@ inline readdir_sequence::const_iterator::class_type& readdir_sequence::const_ite
if(0 != errno)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
- STLSOFT_THROW_X(readdir_sequence_exception("Partial failure of directory enumeration", errno));
+ m_scratch.resize(m_dirLen);
+
+ STLSOFT_THROW_X(readdir_sequence_exception("Partial failure of directory enumeration", errno, m_scratch.c_str()));
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
}
@@ -707,6 +733,8 @@ inline readdir_sequence::const_iterator::class_type& readdir_sequence::const_ite
{
UNIXSTL_ASSERT(NULL != m_entry->d_name);
+ // Check for dots
+
if(0 == (m_flags & includeDots))
{
if(traits_type::is_dots(m_entry->d_name))
@@ -749,7 +777,7 @@ inline readdir_sequence::const_iterator::class_type& readdir_sequence::const_ite
#ifndef _WIN32
// Test for sockets : this version does not support sockets,
// but does elide them from the search results.
- if(S_IFSOCK == (st.st_mode & S_IFMT))
+ if(traits_type::is_socket(&st))
{
continue;
}
Please sign in to comment.
Something went wrong with that request. Please try again.