Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@

## 1.11.1-rc9 - 18th October 2026

* additions:
* **unixstl::filesystem_traits<wchar_t>** — implemented `find_last_path_name_separator()` / `find_next_path_name_separator()` and `is_path_rooted()` / `is_path_absolute()` / `is_path_UNC()` (NUL-terminated and counted), including Windows drive-letter and UNC classification;
* **unixstl::filesystem_traits<wchar_t>** — path-resolve, current-directory, and directory-enumeration members remain declared, pending one conversion policy for that group;
* **unixstl_C_get_home_directory_w()** (**unixstl/system/directory_functions.h**) — reads `HOME` via `getenv()` and converts with `mbstowcs()` (locale multibyte encoding); a short buffer keeps a NUL in the last slot and returns `cchBuffer - 1`, matching the narrow copy;
* **unixstl::system_traits<wchar_t>** — implemented `path_str_compare()` and `path_str_n_compare()` (on Windows, case-folded with `towupper()` and treating `/` and `\` as equivalent);
* **unixstl::system_traits<wchar_t>** — implemented `get_environment_variable()` (raw and resizeable-buffer) by converting the name with `wcstombs()`, reading it with `getenv()`, and converting the value with `mbstowcs()`; implemented the resizeable-buffer overload of `get_home_directory()`;
* **unixstl::system_traits<wchar_t>** — `load_library()` and `free_library()` stay declared together pending one conversion policy (`free_library()` no longer calls `dlclose()` alone); `expand_environment_strings()` remains declared;
* testing:
* Unit tests **test.unit.unixstl.filesystem.filesystem_traits** cover wide separator finding and path classification, and agreement with the narrow specialisation;
* Unit tests **test.unit.unixstl.system.system_traits** cover wide `path_str_compare()` and `path_str_n_compare()`;
* Component tests **test.component.unixstl.system.system_traits** cover wide `get_home_directory()` and `get_environment_variable()` (probe, fixed buffer, and `std::vector` resizeable overload) via `platformstl::environment_variable_scope`;
* Resizeable-buffer cases shared with the resizeable-buffer line (`ensure_dir_end()` / `remove_dir_end()`, and the narrow resizeable `get_home_directory()` / `get_environment_variable()` overloads) remain empty pending that merge;
* docs:
* Normalised Doxygen `\pre` comments to bare boolean expressions (no outer parentheses; no trailing `;` / `.`);
* Prefer `nullptr` over `NULL` / prose in `\pre` text; optional-buffer forms use zero-length check first (`0 == n || nullptr != s`);
Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

| Date | News Item | Details |
| ------------------- | ----------------------------------- | ------- |
| 18th October 2026 | Release of [STLSoft 1.11.1-rc9](https://github.com/synesissoftware/STLSoft/releases/tag/1.11.1-rc9) | `\pre` normalised to bare exprs with `nullptr`; zero-first optional buffers; companion project version bumps |
| 18th October 2026 | Release of [STLSoft 1.11.1-rc9](https://github.com/synesissoftware/STLSoft/releases/tag/1.11.1-rc9) | **unixstl** `wchar_t` path classification and separators; `path_str_*`; wide `get_home_directory()` and `get_environment_variable()`; `\pre` normalised to bare exprs with `nullptr`; companion version bumps |
| 10th October 2026 | Release of [STLSoft 1.11.1-rc8](https://github.com/synesissoftware/STLSoft/releases/tag/1.11.1-rc8) | environment_variable_strtoll()`; `unixstl::filesystem_traits<>::rewind_dir()`; `class_type` and `getenv_s()` empty-variable fixes; component tests; `cmake --build` helper scripts; **run_all_component_tests.sh** / **run_all_automated_tests.sh**; **generate_doxygen.sh**; Linguist classification |
| 30th September 2026 | Release of [STLSoft 1.11.1-rc7](https://github.com/synesissoftware/STLSoft/releases/tag/1.11.1-rc7) | counted NULs; `wchar_t` `string_begins_with`; bit intrinsics; `write_binary()`; `file_lines` mmap (~10–20× vs `fgetc`); compare and allocator units; MinGW static runtime; short test directories; nested **test/performance** |
| 21st September 2026 | Release of [STLSoft 1.11.1-rc6](https://github.com/synesissoftware/STLSoft/releases/tag/1.11.1-rc6) | ACE/ATL/MFC CI; Clang/macOS `stricmp` aliases |
Expand Down
208 changes: 195 additions & 13 deletions include/unixstl/filesystem/filesystem_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@
#define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 4
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 17
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 5
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 0
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 1
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 192
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 193
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */


Expand Down Expand Up @@ -109,6 +109,7 @@

#ifdef _WIN32
# include <ctype.h>
# include <wctype.h>
#endif /* _WIN32 */
#ifndef STLSOFT_INCL_H_ERRNO
# define STLSOFT_INCL_H_ERRNO
Expand Down Expand Up @@ -3010,30 +3011,85 @@ struct filesystem_traits<us_char_w_t>
find_last_path_name_separator(
char_type const* path
)
;
{
UNIXSTL_ASSERT(NULL != path);

char_type const* last = NULL;

for (; L'\0' != *path; ++path)
{
if (is_path_name_separator(*path))
{
last = path;
}
}

return last;
}

static
char_type const*
find_last_path_name_separator(
char_type const* path
, size_t len
)
;
{
UNIXSTL_ASSERT(0 == len || NULL != path);

if (0 == len)
{
return NULL;
}

for (path += (len - 1); 0 != len; --len, --path)
{
if (is_path_name_separator(*path))
{
return path;
}
}

return NULL;
}

static
char_type const*
find_next_path_name_separator(
char_type const* path
)
;
{
UNIXSTL_ASSERT(NULL != path);

for (; L'\0' != *path; ++path)
{
if (is_path_name_separator(*path))
{
return path;
}
}

return NULL;
}

static
char_type const*
find_next_path_name_separator(
char_type const* path
, size_t len
)
;
{
UNIXSTL_ASSERT(0 == len || NULL != path);

for (; 0 != len; --len, ++path)
{
if (is_path_name_separator(*path))
{
return path;
}
}

return NULL;
}

static bool_type is_dots(char_type const* dir)
{
Expand Down Expand Up @@ -3061,31 +3117,153 @@ struct filesystem_traits<us_char_w_t>
}

static bool_type is_path_rooted(char_type const* path)
;
{
UNIXSTL_ASSERT(NULL != path);
#ifdef _WIN32

if (L'\\' == path[0] &&
L'\\' == path[1])
{
return true;
}

if (0 != ::iswalpha(path[0]) &&
L':' == path[1])
{
path += 2;
}
#endif /* _WIN32 */

return is_path_name_separator(*path);
}

static bool_type is_path_rooted(
char_type const* path
, size_t len
)
;
{
UNIXSTL_ASSERT(NULL != path);
#ifdef _WIN32

if (len >= 2)
{
if (L'\\' == path[0] &&
L'\\' == path[1])
{
return true;
}
}

if (len >= 2)
{
if (0 != ::iswalpha(path[0]) &&
L':' == path[1])
{
path += 2;
len -= 2;
}
}
#endif /* _WIN32 */

return 0 != len && is_path_name_separator(*path);
}

static bool_type is_path_absolute(char_type const* path)
;
{
UNIXSTL_ASSERT(NULL != path);
#ifdef _WIN32

if (is_path_UNC(path))
{
return true;
}
if (0 != ::iswalpha(path[0]) &&
L':' == path[1] &&
is_path_name_separator(path[2]))
{
return true;
}

return false;
#else /* ? _WIN32 */

return is_path_rooted(path);
#endif /* _WIN32 */
}

static bool_type is_path_absolute(
char_type const* path
, size_t len
)
;
{
if (0 == len)
{
return false;
}
#ifdef _WIN32

if (is_path_UNC(path, len))
{
return true;
}
if (len >= 3)
{
if (0 != ::iswalpha(path[0]) &&
L':' == path[1] &&
is_path_name_separator(path[2]))
{
return true;
}
}

return false;
#else /* ? _WIN32 */

return is_path_rooted(path, len);
#endif /* _WIN32 */
}

static bool_type is_path_UNC(char_type const* path)
;
{
UNIXSTL_ASSERT(NULL != path);
#ifdef _WIN32

size_type const len = str_len(path);

return is_path_UNC(path, len);
#else /* ? _WIN32 */

STLSOFT_SUPPRESS_UNUSED(path);

return false;
#endif /* _WIN32 */
}

static bool_type is_path_UNC(
char_type const* path
, size_t len
)
;
{
#ifdef _WIN32

switch (len)
{
case 0:
case 1:

return false;
default:

return L'\\' == path[0] && L'\\' == path[1];
}
#else /* ? _WIN32 */

STLSOFT_SUPPRESS_UNUSED(path);
STLSOFT_SUPPRESS_UNUSED(len);

return false;
#endif /* _WIN32 */
}

static bool_type is_path_name_separator(char_type ch)
{
Expand Down Expand Up @@ -3120,6 +3298,10 @@ struct filesystem_traits<us_char_w_t>
return filesystem_traits_::path_max();
}

/* The following path-resolve, cwd, and dir-enumeration members remain
* declared (for API / metaprogramming compatibility) pending a finished
* conversion-policy implementation for the whole group.
*/
static
size_type
get_full_path_name(
Expand Down
Loading
Loading