fixing #29 windows path root separator normalization

This commit is contained in:
Leonard Iklé committed 2022-05-29 16:34:13 +02:00
1 parent 0d22f4fb1f
commit 08e7520d33
7 files changed
+92 -15

No files matched your search

+3 -1
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
<img style="width:100%;" src="/banner.png">
[![Travis Build](https://img.shields.io/travis/likle/cwalk/master.svg?maxAge=2592000&label=Linux%20%26%20MacOS)](https://travis-ci.org/likle/cwalk)
[![Travis Build](https://img.shields.io/travis/likle/cwalk/master.svg?maxAge=2592000&label=Linux%20%26%20MacOS)](https://travis-ci.com/likle/cwalk)
[![Appveyor Build](https://img.shields.io/appveyor/ci/likle/cwalk/master.svg?label=Windows)](https://ci.appveyor.com/project/likle/cwalk)
[![codecov](https://img.shields.io/codecov/c/github/likle/cwalk/master.svg?label=Coverage)](https://codecov.io/gh/likle/cwalk)
[![Language Grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/likle/cwalk.svg?label=Code%20Quality)](https://lgtm.com/projects/g/likle/cwalk/context:cpp)
+6 -5
View File
@@ -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. |
+4 -3
View File
@@ -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
View File
@@ -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.
+19
View File
@@ -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;
+20
View File
@@ -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];