To improve conflict checking, we will need to make these functions
diverge to an extent where having two separate functions will be
preferable.

Signed-off-by: Allan McRae <[email protected]>
---
 lib/libalpm/conflict.c | 79 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 26 deletions(-)

diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 7494fd7..f3b269f 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -213,18 +213,12 @@ alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_handle_t 
*handle,
        return _alpm_innerconflicts(handle, pkglist);
 }
 
-static const int DIFFERENCE = 0;
-static const int INTERSECT = 1;
-/* Returns a set operation on the provided two lists of files.
+/* Returns the difference of the provided two lists of files.
  * Pre-condition: both lists are sorted!
  * When done, free the list but NOT the contained data.
- *
- * Operations:
- *   DIFFERENCE - a difference operation is performed. filesA - filesB.
- *   INTERSECT - an intersection operation is performed. filesA & filesB.
  */
-static alpm_list_t *filelist_operation(alpm_filelist_t *filesA,
-               alpm_filelist_t *filesB, int operation)
+static alpm_list_t *filelist_difference(alpm_filelist_t *filesA,
+               alpm_filelist_t *filesB)
 {
        alpm_list_t *ret = NULL;
        size_t ctrA = 0, ctrB = 0;
@@ -242,26 +236,20 @@ static alpm_list_t *filelist_operation(alpm_filelist_t 
*filesA,
                } else {
                        int cmp = strcmp(strA, strB);
                        if(cmp < 0) {
-                               if(operation == DIFFERENCE) {
-                                       /* item only in filesA, qualifies as a 
difference */
-                                       ret = alpm_list_add(ret, fileA);
-                               }
+                               /* item only in filesA, qualifies as a 
difference */
+                               ret = alpm_list_add(ret, fileA);
                                ctrA++;
                        } else if(cmp > 0) {
                                ctrB++;
                        } else {
-                               if(operation == INTERSECT) {
-                                       /* item in both, qualifies as an 
intersect */
-                                       ret = alpm_list_add(ret, fileA);
-                               }
                                ctrA++;
                                ctrB++;
                        }
-         }
+               }
        }
 
-       /* if doing a difference, ensure we have completely emptied pA */
-       while(operation == DIFFERENCE && ctrA < filesA->count) {
+       /* ensure we have completely emptied pA */
+       while(ctrA < filesA->count) {
                alpm_file_t *fileA = filesA->files + ctrA;
                const char *strA = fileA->name;
                /* skip directories */
@@ -274,6 +262,45 @@ static alpm_list_t *filelist_operation(alpm_filelist_t 
*filesA,
        return ret;
 }
 
+/* Returns the intersection of the provided two lists of files.
+ * Pre-condition: both lists are sorted!
+ * When done, free the list but NOT the contained data.
+ */
+
+static alpm_list_t *filelist_intersection(alpm_filelist_t *filesA,
+               alpm_filelist_t *filesB)
+{
+       alpm_list_t *ret = NULL;
+       size_t ctrA = 0, ctrB = 0;
+
+       while(ctrA < filesA->count && ctrB < filesB->count) {
+               alpm_file_t *fileA = filesA->files + ctrA;
+               alpm_file_t *fileB = filesB->files + ctrB;
+               const char *strA = fileA->name;
+               const char *strB = fileB->name;
+               /* skip directories, we don't care about them */
+               if(strA[strlen(strA)-1] == '/') {
+                       ctrA++;
+               } else if(strB[strlen(strB)-1] == '/') {
+                       ctrB++;
+               } else {
+                       int cmp = strcmp(strA, strB);
+                       if(cmp < 0) {
+                               ctrA++;
+                       } else if(cmp > 0) {
+                               ctrB++;
+                       } else {
+                               /* item in both, qualifies as an intersect */
+                               ret = alpm_list_add(ret, fileA);
+                               ctrA++;
+                               ctrB++;
+                       }
+         }
+       }
+
+       return ret;
+}
+
 /* Adds alpm_fileconflict_t to a conflicts list. Pass the conflicts list, the
  * conflicting file path, and either two packages or one package and NULL.
  */
@@ -438,8 +465,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                for(j = i->next; j; j = j->next) {
                        alpm_list_t *common_files;
                        alpm_pkg_t *p2 = j->data;
-                       common_files = 
filelist_operation(alpm_pkg_get_files(p1),
-                                       alpm_pkg_get_files(p2), INTERSECT);
+                       common_files = 
filelist_intersection(alpm_pkg_get_files(p1),
+                                       alpm_pkg_get_files(p2));
 
                        if(common_files) {
                                alpm_list_t *k;
@@ -471,8 +498,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                if(dbpkg) {
                        alpm_list_t *difference;
                        /* older ver of package currently installed */
-                       difference = filelist_operation(alpm_pkg_get_files(p1),
-                                       alpm_pkg_get_files(dbpkg), DIFFERENCE);
+                       difference = filelist_difference(alpm_pkg_get_files(p1),
+                                       alpm_pkg_get_files(dbpkg));
                        tmpfiles.count = alpm_list_count(difference);
                        tmpfiles.files = alpm_list_to_array(difference, 
tmpfiles.count,
                                        sizeof(alpm_file_t));
@@ -604,7 +631,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                                if(handle->pm_errno == ALPM_ERR_MEMORY) {
                                        FREELIST(conflicts);
                                        if(dbpkg) {
-                                               /* only freed if it was 
generated from filelist_operation() */
+                                               /* only freed if it was 
generated from filelist_difference() */
                                                free(tmpfiles.files);
                                        }
                                        return NULL;
@@ -612,7 +639,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                        }
                }
                if(dbpkg) {
-                       /* only freed if it was generated from 
filelist_operation() */
+                       /* only freed if it was generated from 
filelist_difference() */
                        free(tmpfiles.files);
                }
        }
-- 
1.7.11.2


Reply via email to