removed the condition in alpm_db_set_servers since FREELIST is NULL safe
[pacman-ng.git] / lib / libalpm / filelist.c
blobf6c0ed4513d2b42d294ca07b61c53c872010423c
1 /*
2 * filelist.c
4 * Copyright (c) 2012 Pacman Development Team <pacman-dev@archlinux.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <string.h>
22 /* libalpm */
23 #include "filelist.h"
25 /* Returns the difference of the provided two lists of files.
26 * Pre-condition: both lists are sorted!
27 * When done, free the list but NOT the contained data.
29 alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA,
30 alpm_filelist_t *filesB)
32 alpm_list_t *ret = NULL;
33 size_t ctrA = 0, ctrB = 0;
35 while(ctrA < filesA->count && ctrB < filesB->count) {
36 alpm_file_t *fileA = filesA->files + ctrA;
37 alpm_file_t *fileB = filesB->files + ctrB;
38 const char *strA = fileA->name;
39 const char *strB = fileB->name;
40 /* skip directories, we don't care about them */
41 if(strA[strlen(strA)-1] == '/') {
42 ctrA++;
43 } else if(strB[strlen(strB)-1] == '/') {
44 ctrB++;
45 } else {
46 int cmp = strcmp(strA, strB);
47 if(cmp < 0) {
48 /* item only in filesA, qualifies as a difference */
49 ret = alpm_list_add(ret, fileA);
50 ctrA++;
51 } else if(cmp > 0) {
52 ctrB++;
53 } else {
54 ctrA++;
55 ctrB++;
60 /* ensure we have completely emptied pA */
61 while(ctrA < filesA->count) {
62 alpm_file_t *fileA = filesA->files + ctrA;
63 const char *strA = fileA->name;
64 /* skip directories */
65 if(strA[strlen(strA)-1] != '/') {
66 ret = alpm_list_add(ret, fileA);
68 ctrA++;
71 return ret;
74 /* Returns the intersection of the provided two lists of files.
75 * Pre-condition: both lists are sorted!
76 * When done, free the list but NOT the contained data.
78 alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
79 alpm_filelist_t *filesB)
81 alpm_list_t *ret = NULL;
82 size_t ctrA = 0, ctrB = 0;
84 while(ctrA < filesA->count && ctrB < filesB->count) {
85 alpm_file_t *fileA = filesA->files + ctrA;
86 alpm_file_t *fileB = filesB->files + ctrB;
87 const char *strA = fileA->name;
88 const char *strB = fileB->name;
89 /* skip directories, we don't care about them */
90 if(strA[strlen(strA)-1] == '/') {
91 ctrA++;
92 } else if(strB[strlen(strB)-1] == '/') {
93 ctrB++;
94 } else {
95 int cmp = strcmp(strA, strB);
96 if(cmp < 0) {
97 ctrA++;
98 } else if(cmp > 0) {
99 ctrB++;
100 } else {
101 /* item in both, qualifies as an intersect */
102 ret = alpm_list_add(ret, fileA);
103 ctrA++;
104 ctrB++;
109 return ret;
112 /* Helper function for comparing files list entries
114 int _alpm_files_cmp(const void *f1, const void *f2)
116 const alpm_file_t *file1 = f1;
117 const alpm_file_t *file2 = f2;
118 return strcmp(file1->name, file2->name);
122 alpm_file_t *alpm_filelist_contains(alpm_filelist_t *filelist,
123 const char *path)
125 alpm_file_t key;
127 if(!filelist) {
128 return NULL;
131 key.name = (char *)path;
133 return bsearch(&key, filelist->files, filelist->count,
134 sizeof(alpm_file_t), _alpm_files_cmp);
137 /* vim: set ts=2 sw=2 noet: */