return r;
}
-int pakfire_filelist_contains(struct pakfire_filelist* list, const char* pattern) {
- if (!pattern)
- return -EINVAL;
+static int pakfire_filelist_contains_path(
+ struct pakfire_filelist* list, const char* path) {
+ const char* p = NULL;
+ int i;
+ int r;
+
+ // Set starting points
+ int lo = 0;
+ int hi = list->num_files - 1;
+ while (lo <= hi) {
+ // Find the middle
+ i = lo + (hi - lo) / 2;
+
+ // Fetch the package path
+ p = pakfire_file_get_path(list->files[i]);
+ if (!p)
+ return -EINVAL;
+
+ // Compare the paths
+ r = strcmp(p, path);
+
+ // We found a match
+ if (r == 0)
+ return 1;
+
+ // Search the right half
+ else if (r < 0)
+ lo = i + 1;
+
+ // Search the left half
+ else if (r > 0)
+ hi = i - 1;
+ }
+
+ // No match
+ return 0;
+}
+
+static int pakfire_filelist_contains_pattern(
+ struct pakfire_filelist* list, const char* pattern) {
for (unsigned int i = 0; i < list->num_files; i++) {
const char* path = pakfire_file_get_path(list->files[i]);
if (!path)
return 0;
}
+int pakfire_filelist_contains(struct pakfire_filelist* list, const char* pattern) {
+ if (!pattern)
+ return -EINVAL;
+
+ // If this is a pattern, we perform a naive search
+ if (pakfire_path_is_pattern(pattern))
+ return pakfire_filelist_contains_pattern(list, pattern);
+
+ // Otherwise we perform a binary search to be faster
+ return pakfire_filelist_contains_path(list, pattern);
+}
+
int pakfire_filelist_walk(struct pakfire_filelist* list,
pakfire_filelist_walk_callback callback, void* data, int flags, const char* title) {
struct pakfire_progress* progress = NULL;
int __pakfire_path_absolute(char* buffer, const size_t length, const char* s);
int pakfire_path_match(const char* p, const char* s);
+int pakfire_path_is_pattern(const char* path);
#define pakfire_path_replace_extension(path, extension) \
__pakfire_path_replace_extension(path, sizeof(path), extension)