| 80 | } |
| 81 | |
| 82 | void sortFileList(std::vector<std::string>& strs) { |
| 83 | std::sort(begin(strs), end(strs), [](const std::string& str1, const std::string& str2) { |
| 84 | // Directories first |
| 85 | bool isDir1 = str1.back() == '/'; |
| 86 | bool isDir2 = str2.back() == '/'; |
| 87 | if (isDir1 != isDir2) return isDir1; |
| 88 | |
| 89 | // Start naive natural sort |
| 90 | const char* s1 = str1.c_str(); |
| 91 | const char* s2 = str2.c_str(); |
| 92 | |
| 93 | // Iterate while both strings have characters |
| 94 | while (*s1 && *s2) { |
| 95 | // Check if both are at the start of a number |
| 96 | if (isdigit(*s1) && isdigit(*s2)) { |
| 97 | // Skip leading zeros and track them |
| 98 | while (*s1 == '0') s1++; |
| 99 | while (*s2 == '0') s2++; |
| 100 | |
| 101 | // Count digits to compare lengths first |
| 102 | int len1 = 0, len2 = 0; |
| 103 | while (isdigit(s1[len1])) len1++; |
| 104 | while (isdigit(s2[len2])) len2++; |
| 105 | |
| 106 | // Different length so return smaller integer value |
| 107 | if (len1 != len2) return len1 < len2; |
| 108 | |
| 109 | // Same length so compare digit by digit |
| 110 | for (int i = 0; i < len1; i++) { |
| 111 | if (s1[i] != s2[i]) return s1[i] < s2[i]; |
| 112 | } |
| 113 | |
| 114 | // Numbers equal so advance pointers |
| 115 | s1 += len1; |
| 116 | s2 += len2; |
| 117 | } else { |
| 118 | // Regular case-insensitive character comparison |
| 119 | char c1 = tolower(*s1); |
| 120 | char c2 = tolower(*s2); |
| 121 | if (c1 != c2) return c1 < c2; |
| 122 | s1++; |
| 123 | s2++; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | // One string is prefix of other |
| 128 | return *s1 == '\0' && *s2 != '\0'; |
| 129 | }); |
| 130 | } |
| 131 | |
| 132 | bool checkFileExtension(std::string_view fileName, const char* extension) { |
| 133 | const size_t extLen = strlen(extension); |
no test coverage detected