From a933a40462e6bd380396d66b6e8118b60a2a73bb Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 31 Dec 2021 20:46:13 -0600 Subject: [PATCH] Update: f_path related improvements. Return F_data_not rather than F_false to provide a more detailed reason as to the return status of f_path_is(). Explicitly check fo F_true when calling f_path_is() because it now returns F_data_not without the error bit. Add f_path_is_relative(). Pretty much every path that does not begin with a "/" is a relative path. This function performs a dirt simple check to achieve this. This function does not perform any checks to see if the path would be a valid path. Such decisions are filesystem and are otherwise too situation dependent to be reliable detect in a general manner. Use f_path_separator_s rather than an explicit "/". Simplify counter using a pre-increment within the if condition check. --- level_0/f_path/c/path.c | 65 ++++++++++++++++++++++++++++- level_0/f_path/c/path.h | 59 ++++++++++++++++++++++++-- level_2/fll_path/c/path.c | 10 ++--- level_3/fake/c/private-fake-path_generate.c | 4 +- 4 files changed, 125 insertions(+), 13 deletions(-) diff --git a/level_0/f_path/c/path.c b/level_0/f_path/c/path.c index a3d6486..d1aef35 100644 --- a/level_0/f_path/c/path.c +++ b/level_0/f_path/c/path.c @@ -94,8 +94,9 @@ extern "C" { #ifndef _di_f_path_is_ f_status_t f_path_is(const f_string_t path, const f_array_length_t length) { + if (!path || !length) { - return F_false; + return F_data_not; } for (f_array_length_t i = 0; i < length; ++i) { @@ -109,6 +110,68 @@ extern "C" { } #endif // _di_f_path_is_ +#ifndef _di_f_path_is_relative_ + f_status_t f_path_is_relative(const f_string_t path, const f_array_length_t length) { + + if (!path || !length) { + return F_data_not; + } + + f_array_length_t i = 0; + + for (; i < length; ++i) { + if (path[i]) break; + } // for + + if (path[i] == f_path_separator_s[0]) { + return F_false; + } + + return F_true; + } +#endif // _di_f_path_is_relative_ + +#ifndef _di_f_path_is_relative_current_ + f_status_t f_path_is_relative_current(const f_string_t path, const f_array_length_t length) { + + if (!path || !length) { + return F_data_not; + } + + f_array_length_t i = 0; + + for (; i < length; ++i) { + if (path[i]) break; + } // for + + if (path[i] == f_path_separator_s[0]) { + return F_false; + } + + if (path[i] == f_path_separator_current_s[0]) { + for (; i < length; ++i) { + if (path[i]) break; + } // for + + if (path[i] == f_path_separator_s[0]) { + return F_true; + } + + if (path[i] == f_path_separator_current_s[0]) { + for (; i < length; ++i) { + if (path[i]) break; + } // for + + if (path[i] == f_path_separator_s[0]) { + return F_true; + } + } + } + + return F_false; + } +#endif // _di_f_path_is_relative_current_ + #ifndef _di_f_path_real_ f_status_t f_path_real(const f_string_t path, f_string_dynamic_t *real) { #ifndef _di_level_0_parameter_checking_ diff --git a/level_0/f_path/c/path.h b/level_0/f_path/c/path.h index 5cfe093..f210d43 100644 --- a/level_0/f_path/c/path.h +++ b/level_0/f_path/c/path.h @@ -121,23 +121,74 @@ extern "C" { /** * Identify whether or not a string represents a path string. * + * This does not check to see if the path exists or not. + * This does not stop on NULL (NULL characters are ignored). + * * A string without any path parts that could be a path is not considered a path by this function. * That is to say "my_file.txt" is not a path string but "./my_file.txt" is a path string. * * @param path - * The string that may or may not represent a path.. + * The string that may or may not represent a path. * @param length - * Length of the path string. + * Length of the string. * * @return - * F_true if this string is a path string. - * F_false if this string is not a path string. + * F_true if the string is a path string. + * F_false if the string is not a path string. + * F_data_not if the string has a length of 0 or the string is NULL. */ #ifndef _di_f_path_is_ extern f_status_t f_path_is(const f_string_t path, const f_array_length_t length); #endif // _di_f_path_is_ /** + * Identify whether or not a string represents a relative path string. + * + * This does not check to see if the path exists or not. + * This does not stop on NULL (NULL characters are ignored). + * + * A string without any path parts that could be a path is considered a relative path by this function. + * That is to say "my_file.txt" is a relative path string. + * + * @param path + * The string that may or may not represent a relative path. + * @param length + * Length of the path string. + * + * @return + * F_true if the string is a relative path string. + * F_false if the string is not a relative path string. + * F_data_not if the string has a length of 0 or the string is NULL. + */ +#ifndef _di_f_path_is_relative_ + extern f_status_t f_path_is_relative(const f_string_t path, const f_array_length_t length); +#endif // _di_f_path_is_relative_ + +/** + * Identify whether or not a string explicitly represents a relative path string to the current working directory. + * + * This does not check to see if the path exists or not. + * This does not stop on NULL (NULL characters are ignored). + * + * A string that is explicitly relative to the current working directory must begin with one of "./" or "../". + * + * This does not return true for paths that are implicitly relative, such as "abc". + * + * @param path + * The string that may or may not represent a relative path. + * @param length + * Length of the path string. + * + * @return + * F_true if the string is a relative path string. + * F_false if the string is not a relative path string. + * F_data_not if the string has a length of 0 or the string is NULL. + */ +#ifndef _di_f_path_is_relative_current_ + extern f_status_t f_path_is_relative_current(const f_string_t path, const f_array_length_t length); +#endif // _di_f_path_is_relative_current_ + +/** * Get the real path for the given path. * * This does check to see if the path exists or not (path must exist). diff --git a/level_2/fll_path/c/path.c b/level_2/fll_path/c/path.c index 56a3de5..b9804d2 100644 --- a/level_2/fll_path/c/path.c +++ b/level_2/fll_path/c/path.c @@ -35,7 +35,7 @@ extern "C" { at = 0; } - status = f_string_append_assure("/", 1, canonical); + status = f_string_append_assure(f_path_separator_s, 1, canonical); if (F_status_is_error(status)) return status; for (; path[at]; ++at) { @@ -78,9 +78,7 @@ extern "C" { } } else { - ++size_chunk; - - if (size_chunk) { + if (++size_chunk) { status = f_string_append(path + position, size_chunk, canonical); if (F_status_is_error(status)) return status; } @@ -128,9 +126,9 @@ extern "C" { } } - // assure there is no trailing forward slash, unless it is the first slash. + // Assure there is no trailing forward slash, unless it is the first slash. if (canonical->used > 1 && canonical->string[canonical->used - 1] == f_path_separator_s[0]) { - canonical->used--; + --canonical->used; } status = f_string_dynamic_terminate_after(canonical); diff --git a/level_3/fake/c/private-fake-path_generate.c b/level_3/fake/c/private-fake-path_generate.c index 309eacf..3978581 100644 --- a/level_3/fake/c/private-fake-path_generate.c +++ b/level_3/fake/c/private-fake-path_generate.c @@ -194,11 +194,11 @@ extern "C" { } // When custom fakefile or settings are used and they are paths to a file, remove the default path. - if (f_path_is(main->fakefile.string, main->fakefile.used)) { + if (f_path_is(main->fakefile.string, main->fakefile.used) == F_true) { main->file_data_build_fakefile.used = 0; } - if (f_path_is(main->settings.string, main->settings.used)) { + if (f_path_is(main->settings.string, main->settings.used) == F_true) { main->file_data_build_settings.used = 0; } -- 1.8.3.1