Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added cwk_path_get_basename_wout_extension() #50

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ if(ENABLE_TESTS)
create_test(DEFAULT absolute check)
create_test(DEFAULT absolute buffer_reuse)
create_test(DEFAULT basename simple)
create_test(DEFAULT basename simple_wout_extension)
create_test(DEFAULT basename empty)
create_test(DEFAULT basename trailing_separator)
create_test(DEFAULT basename trailing_separators)
create_test(DEFAULT basename trailing_separators_wout_extension)
create_test(DEFAULT basename no_separators)
create_test(DEFAULT basename no_separators_wout_extension)
create_test(DEFAULT basename special_directories)
create_test(DEFAULT basename root)
create_test(DEFAULT basename windows)
Expand Down
15 changes: 15 additions & 0 deletions include/cwalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,21 @@ CWK_PUBLIC bool cwk_path_is_relative(const char *path);
CWK_PUBLIC void cwk_path_get_basename(const char *path, const char **basename,
size_t *length);

/**
* @brief Gets the basename without the extension of a file path.
*
* This is identical to cwk_path_get_basename(), except that the returned
* length does not account for the file extension if there is one. If there is
* no extension, the result is identical to cwk_path_get_basename().
*
* @param path The path which will be inspected.
* @param basename The output of the basename pointer.
* @param length The output of the length of the basename not accounting for
* the extension. This may be null if not required.
*/
CWK_PUBLIC void cwk_path_get_basename_wout_extension(const char *path,
const char **basename, size_t *length);

/**
* @brief Changes the basename of a file path.
*
Expand Down
31 changes: 31 additions & 0 deletions src/cwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,37 @@ void cwk_path_get_basename(const char *path, const char **basename,
}
}

void cwk_path_get_basename_wout_extension(const char *path,
const char **basename, size_t *length)
{
struct cwk_segment segment;
const char *c;

// We get the last segment of the path. The last segment will contain the
// basename if there is any. If there are no segments we will set the basename
// to NULL and the length to 0.
if (!cwk_path_get_last_segment(path, &segment)) {
*basename = NULL;
if (length) {
*length = 0;
}
return;
}

*basename = segment.begin;
if (length) {
*length = segment.size;

for (c = segment.end; c >= segment.begin; --c) {
if (*c == '.') {
// Okay, we found an extension. We can stop looking now.
*length = (size_t)(c - segment.begin);
return;
}
}
}
}

size_t cwk_path_change_basename(const char *path, const char *new_basename,
char *buffer, size_t buffer_size)
{
Expand Down
60 changes: 60 additions & 0 deletions test/basename_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,26 @@ int basename_no_separators(void)
return EXIT_SUCCESS;
}

int basename_no_separators_wout_extension(void)
{
const char *path, *basename;
size_t length;

cwk_path_set_style(CWK_STYLE_UNIX);
path = "file_name";
cwk_path_get_basename_wout_extension(path, &basename, &length);

if (length != 9) {
return EXIT_FAILURE;
}

if (strncmp(basename, "file_name", length) != 0) {
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

int basename_trailing_separators(void)
{
const char *path, *basename;
Expand All @@ -252,6 +272,26 @@ int basename_trailing_separators(void)
return EXIT_SUCCESS;
}

int basename_trailing_separators_wout_extension(void)
{
const char *path, *basename;
size_t length;

cwk_path_set_style(CWK_STYLE_UNIX);
path = "/my/path.txt////";
cwk_path_get_basename_wout_extension(path, &basename, &length);

if (length != 4) {
return EXIT_FAILURE;
}

if (strncmp(basename, "path", length) != 0) {
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

int basename_trailing_separator(void)
{
const char *path, *basename;
Expand Down Expand Up @@ -311,3 +351,23 @@ int basename_simple(void)

return EXIT_SUCCESS;
}

int basename_simple_wout_extension(void)
{
const char *path, *basename;
size_t length;

cwk_path_set_style(CWK_STYLE_UNIX);
path = "/my/path.txt";
cwk_path_get_basename_wout_extension(path, &basename, &length);

if (length != 4) {
return EXIT_FAILURE;
}

if (strncmp(basename, "path", length) != 0) {
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}