mirror of
https://github.com/likle/cwalk.git
synced 2026-10-28 09:44:01 +00:00
fixing #29 windows path root separator normalization
This commit is contained in:
1 parent
0d22f4fb1f
commit
08e7520d33
7 files changed
+92
-15
No files matched your search
+3
-1
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.9.2)
|
||||
|
||||
# set project name
|
||||
project(cwalk
|
||||
VERSION 1.2.5
|
||||
VERSION 1.2.7
|
||||
DESCRIPTION "A simple path library"
|
||||
LANGUAGES C)
|
||||
|
||||
@@ -175,6 +175,7 @@ if(ENABLE_TESTS)
|
||||
create_test(DEFAULT normalize empty)
|
||||
create_test(DEFAULT normalize only_separators)
|
||||
create_test(DEFAULT normalize back_after_root)
|
||||
create_test(DEFAULT normalize forward_slashes)
|
||||
create_test(DEFAULT relative simple)
|
||||
create_test(DEFAULT relative relative)
|
||||
create_test(DEFAULT relative long_base)
|
||||
@@ -191,6 +192,7 @@ if(ENABLE_TESTS)
|
||||
create_test(DEFAULT relative check)
|
||||
create_test(DEFAULT relative root_path_unix)
|
||||
create_test(DEFAULT relative root_path_windows)
|
||||
create_test(DEFAULT relative root_forward_slashes)
|
||||
create_test(DEFAULT root absolute)
|
||||
create_test(DEFAULT root unc)
|
||||
create_test(DEFAULT root device_unc)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<img style="width:100%;" src="/banner.png">
|
||||
|
||||
[](https://travis-ci.org/likle/cwalk)
|
||||
[](https://travis-ci.com/likle/cwalk)
|
||||
[](https://ci.appveyor.com/project/likle/cwalk)
|
||||
[](https://codecov.io/gh/likle/cwalk)
|
||||
[](https://lgtm.com/projects/g/likle/cwalk/context:cpp)
|
||||
|
||||
@@ -64,8 +64,9 @@ The relative path is: ../world
|
||||
|
||||
## Changelog
|
||||
|
||||
| Version | Description |
|
||||
|------------|--------------------------------------------------------|
|
||||
| **v1.2.5** | Fixed calls with path without segments. |
|
||||
| **v1.2.5** | Fixed calls with unequal roots in paths. |
|
||||
| **v1.0.0** | The function is introduced. |
|
||||
| Version | Description |
|
||||
|------------|---------------------------------------------------|
|
||||
| **v1.2.7** | Fixed windows paths with forward slashes in root. |
|
||||
| **v1.2.5** | Fixed calls with path without segments. |
|
||||
| **v1.2.5** | Fixed calls with unequal roots in paths. |
|
||||
| **v1.0.0** | The function is introduced. |
|
||||
@@ -68,6 +68,7 @@ Output:
|
||||
|
||||
## Changelog
|
||||
|
||||
| Version | Description |
|
||||
|------------|--------------------------------------------------------|
|
||||
| **v1.0.0** | The function is introduced. |
|
||||
| Version | Description |
|
||||
|------------|---------------------------------------------------|
|
||||
| **v1.2.7** | Fixed windows paths with forward slashes in root. |
|
||||
| **v1.0.0** | The function is introduced. |
|
||||
+39
-5
@@ -124,7 +124,9 @@ static void cwk_path_terminate_output(char *buffer, size_t buffer_size,
|
||||
static bool cwk_path_is_string_equal(const char *first, const char *second,
|
||||
size_t first_size, size_t second_size)
|
||||
{
|
||||
// THe two strings are not equal if the sizes are not equal.
|
||||
bool are_both_separators;
|
||||
|
||||
// The two strings are not equal if the sizes are not equal.
|
||||
if (first_size != second_size) {
|
||||
return false;
|
||||
}
|
||||
@@ -140,11 +142,18 @@ static bool cwk_path_is_string_equal(const char *first, const char *second,
|
||||
// own.
|
||||
while (*first && *second && first_size > 0) {
|
||||
// We can consider the string to be not equal if the two lowercase
|
||||
// characters are not equal.
|
||||
if (tolower(*first++) != tolower(*second++)) {
|
||||
// characters are not equal. The two chars may also be separators, which
|
||||
// means they would be equal.
|
||||
are_both_separators = strchr(separators[path_style], *first) != NULL &&
|
||||
strchr(separators[path_style], *second) != NULL;
|
||||
|
||||
if (tolower(*first) != tolower(*second) && !are_both_separators) {
|
||||
return false;
|
||||
}
|
||||
|
||||
first++;
|
||||
second++;
|
||||
|
||||
--first_size;
|
||||
}
|
||||
|
||||
@@ -482,7 +491,7 @@ static void cwk_path_get_root_windows(const char *path, size_t *length)
|
||||
if (cwk_path_is_separator(c)) {
|
||||
++c;
|
||||
|
||||
// Check whether the path starts with a single back slash, which means this
|
||||
// Check whether the path starts with a single backslash, which means this
|
||||
// is not a network path - just a normal path starting with a backslash.
|
||||
if (!cwk_path_is_separator(c)) {
|
||||
// Okay, this is not a network path but we still use the backslash as a
|
||||
@@ -570,6 +579,29 @@ static bool cwk_path_is_root_absolute(const char *path, size_t length)
|
||||
return cwk_path_is_separator(&path[length - 1]);
|
||||
}
|
||||
|
||||
static void cwk_path_fix_root(char *buffer, size_t buffer_size, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// This only affects windows.
|
||||
if (path_style != CWK_STYLE_WINDOWS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we are not writing further than we are actually allowed to.
|
||||
if (length > buffer_size) {
|
||||
length = buffer_size;
|
||||
}
|
||||
|
||||
// Replace all forward slashes with backwards slashes. Since this is windows
|
||||
// we can't have any forward slashes in the root.
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (cwk_path_is_separator(&buffer[i])) {
|
||||
buffer[i] = *separators[CWK_STYLE_WINDOWS];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t cwk_path_join_and_normalize_multiple(const char **paths,
|
||||
char *buffer, size_t buffer_size)
|
||||
{
|
||||
@@ -584,8 +616,10 @@ static size_t cwk_path_join_and_normalize_multiple(const char **paths,
|
||||
// later on whether we can remove superfluous "../" or not.
|
||||
absolute = cwk_path_is_root_absolute(paths[0], pos);
|
||||
|
||||
// First copy the root to the output. We will not modify the root.
|
||||
// First copy the root to the output. After copying, we will normalize the
|
||||
// root.
|
||||
cwk_path_output_sized(buffer, buffer_size, 0, paths[0], pos);
|
||||
cwk_path_fix_root(buffer, buffer_size, pos);
|
||||
|
||||
// So we just grab the first segment. If there is no segment we will always
|
||||
// output a "/", since we currently only support absolute paths here.
|
||||
|
||||
@@ -6,6 +6,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int normalize_forward_slashes()
|
||||
{
|
||||
size_t count;
|
||||
char result[FILENAME_MAX];
|
||||
char *input, *expected;
|
||||
|
||||
cwk_path_set_style(CWK_STYLE_WINDOWS);
|
||||
|
||||
input = "C:/this/is/a/test/path";
|
||||
strcpy(result, input);
|
||||
expected = "C:\\this\\is\\a\\test\\path";
|
||||
count = cwk_path_normalize(result, result, sizeof(result));
|
||||
if (count != strlen(expected) || strcmp(result, expected) != 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int normalize_back_after_root()
|
||||
{
|
||||
size_t count;
|
||||
|
||||
@@ -6,6 +6,26 @@
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
int relative_root_forward_slashes()
|
||||
{
|
||||
char result[FILENAME_MAX];
|
||||
size_t length;
|
||||
|
||||
cwk_path_set_style(CWK_STYLE_WINDOWS);
|
||||
|
||||
length = cwk_path_get_relative("C:\\foo\\bar\\baz\\", "C:/foo/bar/file.txt",
|
||||
result, sizeof(result));
|
||||
if (length != 11) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(result, "..\\file.txt") != 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int relative_root_path_windows()
|
||||
{
|
||||
char result[FILENAME_MAX];
|
||||
|
||||
Reference in new issue
Block a user