Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/intern/path_util.c
| Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
| * (eg A:\) or is a UNC path. | * (eg A:\) or is a UNC path. | ||||
| */ | */ | ||||
| static bool BLI_path_is_abs(const char *name); | static bool BLI_path_is_abs(const char *name); | ||||
| #endif /* WIN32 */ | #endif /* WIN32 */ | ||||
| // #define DEBUG_STRSIZE | // #define DEBUG_STRSIZE | ||||
| /** | |||||
| * On UNIX it only makes sense to treat `/` as a path separator. | |||||
| * On WIN32 either may be used. | |||||
| */ | |||||
| static bool is_sep_native_compat(const char ch) | |||||
| { | |||||
| if (ch == SEP) { | |||||
| return true; | |||||
| } | |||||
| #ifdef WIN32 | |||||
| if (ch == ALTSEP) { | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| return false; | |||||
| } | |||||
| /* implementation */ | /* implementation */ | ||||
| int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_digits_len) | int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_digits_len) | ||||
| { | { | ||||
| uint nums = 0, nume = 0; | uint nums = 0, nume = 0; | ||||
| int i; | int i; | ||||
| bool found_digit = false; | bool found_digit = false; | ||||
| const char *const lslash = BLI_path_slash_rfind(string); | const char *const lslash = BLI_path_slash_rfind(string); | ||||
| ▲ Show 20 Lines • Show All 1,465 Lines • ▼ Show 20 Lines | #ifdef WIN32 | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* Remove trailing slashes, unless there are *only* trailing slashes | /* Remove trailing slashes, unless there are *only* trailing slashes | ||||
| * (allow `//` or `//some_path` as the first argument). */ | * (allow `//` or `//some_path` as the first argument). */ | ||||
| bool has_trailing_slash = false; | bool has_trailing_slash = false; | ||||
| if (ofs != 0) { | if (ofs != 0) { | ||||
| size_t len = ofs; | size_t len = ofs; | ||||
| while ((len != 0) && (path[len - 1] == SEP)) { | while ((len != 0) && is_sep_native_compat(path[len - 1])) { | ||||
| len -= 1; | len -= 1; | ||||
| } | } | ||||
| if (len != 0) { | if (len != 0) { | ||||
| ofs = len; | ofs = len; | ||||
| } | } | ||||
| has_trailing_slash = (path[len] != '\0'); | has_trailing_slash = (path[len] != '\0'); | ||||
| } | } | ||||
| for (int path_index = 1; path_index < path_array_num; path_index++) { | for (int path_index = 1; path_index < path_array_num; path_index++) { | ||||
| path = path_array[path_index]; | path = path_array[path_index]; | ||||
| has_trailing_slash = false; | has_trailing_slash = false; | ||||
| const char *path_init = path; | const char *path_init = path; | ||||
| while (path[0] == SEP) { | while (is_sep_native_compat(path[0])) { | ||||
| path++; | path++; | ||||
| } | } | ||||
| size_t len = strlen(path); | size_t len = strlen(path); | ||||
| if (len != 0) { | if (len != 0) { | ||||
| while ((len != 0) && (path[len - 1] == SEP)) { | while ((len != 0) && is_sep_native_compat(path[len - 1])) { | ||||
| len -= 1; | len -= 1; | ||||
| } | } | ||||
| if (len != 0) { | if (len != 0) { | ||||
| /* the very first path may have a slash at the end */ | /* the very first path may have a slash at the end */ | ||||
| if (ofs && (dst[ofs - 1] != SEP)) { | if (ofs && !is_sep_native_compat(dst[ofs - 1])) { | ||||
| dst[ofs++] = SEP; | dst[ofs++] = SEP; | ||||
| if (ofs == dst_last) { | if (ofs == dst_last) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| has_trailing_slash = (path[len] != '\0'); | has_trailing_slash = (path[len] != '\0'); | ||||
| if (ofs + len >= dst_last) { | if (ofs + len >= dst_last) { | ||||
| len = dst_last - ofs; | len = dst_last - ofs; | ||||
| } | } | ||||
| memcpy(&dst[ofs], path, len); | memcpy(&dst[ofs], path, len); | ||||
| ofs += len; | ofs += len; | ||||
| if (ofs == dst_last) { | if (ofs == dst_last) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| has_trailing_slash = (path_init != path); | has_trailing_slash = (path_init != path); | ||||
| } | } | ||||
| } | } | ||||
| if (has_trailing_slash) { | if (has_trailing_slash) { | ||||
| if ((ofs != dst_last) && (ofs != 0) && (dst[ofs - 1] != SEP)) { | if ((ofs != dst_last) && (ofs != 0) && !is_sep_native_compat(dst[ofs - 1])) { | ||||
| dst[ofs++] = SEP; | dst[ofs++] = SEP; | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(ofs <= dst_last); | BLI_assert(ofs <= dst_last); | ||||
| dst[ofs] = '\0'; | dst[ofs] = '\0'; | ||||
| return ofs; | return ofs; | ||||
| Show All 11 Lines | static bool path_name_at_index_forward(const char *__restrict path, | ||||
| int *__restrict r_len) | int *__restrict r_len) | ||||
| { | { | ||||
| BLI_assert(index >= 0); | BLI_assert(index >= 0); | ||||
| int index_step = 0; | int index_step = 0; | ||||
| int prev = -1; | int prev = -1; | ||||
| int i = 0; | int i = 0; | ||||
| while (true) { | while (true) { | ||||
| const char c = path[i]; | const char c = path[i]; | ||||
| if (ELEM(c, SEP, '\0')) { | if ((c == '\0') || is_sep_native_compat(c)) { | ||||
| if (prev + 1 != i) { | if (prev + 1 != i) { | ||||
| prev += 1; | prev += 1; | ||||
| /* Skip '/./' (behave as if they don't exist). */ | /* Skip '/./' (behave as if they don't exist). */ | ||||
| if (!((i - prev == 1) && (prev != 0) && (path[prev] == '.'))) { | if (!((i - prev == 1) && (prev != 0) && (path[prev] == '.'))) { | ||||
| if (index_step == index) { | if (index_step == index) { | ||||
| *r_offset = prev; | *r_offset = prev; | ||||
| *r_len = i - prev; | *r_len = i - prev; | ||||
| return true; | return true; | ||||
| Show All 18 Lines | |||||
| { | { | ||||
| /* Negative number, reverse where -1 is the last element. */ | /* Negative number, reverse where -1 is the last element. */ | ||||
| BLI_assert(index < 0); | BLI_assert(index < 0); | ||||
| int index_step = -1; | int index_step = -1; | ||||
| int prev = strlen(path); | int prev = strlen(path); | ||||
| int i = prev - 1; | int i = prev - 1; | ||||
| while (true) { | while (true) { | ||||
| const char c = i >= 0 ? path[i] : '\0'; | const char c = i >= 0 ? path[i] : '\0'; | ||||
| if (ELEM(c, SEP, '\0')) { | if ((c == '\0') || is_sep_native_compat(c)) { | ||||
| if (prev - 1 != i) { | if (prev - 1 != i) { | ||||
| i += 1; | i += 1; | ||||
| /* Skip '/./' (behave as if they don't exist). */ | /* Skip '/./' (behave as if they don't exist). */ | ||||
| if (!((prev - i == 1) && (i != 0) && (path[i] == '.'))) { | if (!((prev - i == 1) && (i != 0) && (path[i] == '.'))) { | ||||
| if (index_step == index) { | if (index_step == index) { | ||||
| *r_offset = i; | *r_offset = i; | ||||
| *r_len = prev - i; | *r_len = prev - i; | ||||
| return true; | return true; | ||||
| ▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines | |||||