No new behaviour introduced, everything should work exactly as before.

Signed-off-by: Benedikt Morbach <[email protected]>
---
 lib/libalpm/be_local.c   |   12 ++++++-
 lib/libalpm/be_package.c |    5 ++-
 lib/libalpm/be_sync.c    |    8 ++++-
 lib/libalpm/package.c    |    7 +++-
 src/pacman/package.c     |   18 ++++++++++-
 src/pacman/util.c        |   73 ++++++++++++++++++++++++++++++++++++++-------
 6 files changed, 102 insertions(+), 21 deletions(-)

diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 21d2748..6a578ff 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -517,6 +517,12 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t 
*info, const char *filena
        f = alpm_list_add(f, _alpm_splitdep(line)); \
 } while(1) /* note the while(1) and not (0) */
 
+#define READ_AND_SPLITOPTDEP(f) do { \
+       if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
+       if(_alpm_strip_newline(line) == 0) break; \
+       f = alpm_list_add(f, _alpm_splitoptdep(line)); \
+} while(1) /* note the while(1) and not (0) */
+
 static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
 {
        FILE *fp = NULL;
@@ -613,7 +619,7 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t 
inforeq)
                        } else if(strcmp(line, "%DEPENDS%") == 0) {
                                READ_AND_SPLITDEP(info->depends);
                        } else if(strcmp(line, "%OPTDEPENDS%") == 0) {
-                               READ_AND_STORE_ALL(info->optdepends);
+                               READ_AND_SPLITOPTDEP(info->optdepends);
                        } else if(strcmp(line, "%CONFLICTS%") == 0) {
                                READ_AND_SPLITDEP(info->conflicts);
                        } else if(strcmp(line, "%PROVIDES%") == 0) {
@@ -824,7 +830,9 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, 
alpm_dbinfrq_t inforeq
                if(info->optdepends) {
                        fputs("%OPTDEPENDS%\n", fp);
                        for(lp = info->optdepends; lp; lp = lp->next) {
-                               fprintf(fp, "%s\n", (char *)lp->data);
+                               char *optstring = 
alpm_optdep_compute_string(lp->data);
+                               fprintf(fp, "%s\n", optstring);
+                               free(optstring);
                        }
                        fprintf(fp, "\n");
                }
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 4f530e0..be6e4c8 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -38,7 +38,7 @@
 #include "log.h"
 #include "handle.h"
 #include "package.h"
-#include "deps.h" /* _alpm_splitdep */
+#include "deps.h"
 
 struct package_changelog {
        struct archive *archive;
@@ -213,7 +213,8 @@ static int parse_descfile(alpm_handle_t *handle, struct 
archive *a, alpm_pkg_t *
                                alpm_depend_t *dep = _alpm_splitdep(ptr);
                                newpkg->depends = 
alpm_list_add(newpkg->depends, dep);
                        } else if(strcmp(key, "optdepend") == 0) {
-                               newpkg->optdepends = 
alpm_list_add(newpkg->optdepends, strdup(ptr));
+                               alpm_optdepend_t *optdep = 
_alpm_splitoptdep(ptr);
+                               newpkg->optdepends = 
alpm_list_add(newpkg->optdepends, optdep);
                        } else if(strcmp(key, "conflict") == 0) {
                                alpm_depend_t *conflict = _alpm_splitdep(ptr);
                                newpkg->conflicts = 
alpm_list_add(newpkg->conflicts, conflict);
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 54c4f87..0aaf085 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -504,6 +504,12 @@ cleanup:
        f = alpm_list_add(f, _alpm_splitdep(line)); \
 } while(1) /* note the while(1) and not (0) */
 
+#define READ_AND_SPLITOPTDEP(f) do { \
+       if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
+       if(_alpm_strip_newline(buf.line) == 0) break; \
+       f = alpm_list_add(f, _alpm_splitoptdep(line)); \
+} while(1) /* note the while(1) and not (0) */
+
 static int sync_db_read(alpm_db_t *db, struct archive *archive,
                struct archive_entry *entry, alpm_pkg_t **likely_pkg)
 {
@@ -590,7 +596,7 @@ static int sync_db_read(alpm_db_t *db, struct archive 
*archive,
                        } else if(strcmp(line, "%DEPENDS%") == 0) {
                                READ_AND_SPLITDEP(pkg->depends);
                        } else if(strcmp(line, "%OPTDEPENDS%") == 0) {
-                               READ_AND_STORE_ALL(pkg->optdepends);
+                               READ_AND_SPLITOPTDEP(pkg->optdepends);
                        } else if(strcmp(line, "%CONFLICTS%") == 0) {
                                READ_AND_SPLITDEP(pkg->conflicts);
                        } else if(strcmp(line, "%PROVIDES%") == 0) {
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 2a97177..451506b 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -531,7 +531,9 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
        for(i = pkg->depends; i; i = i->next) {
                newpkg->depends = alpm_list_add(newpkg->depends, 
_alpm_dep_dup(i->data));
        }
-       newpkg->optdepends = alpm_list_strdup(pkg->optdepends);
+       for(i = pkg->optdepends; i; i = i->next) {
+               newpkg->optdepends = alpm_list_add(newpkg->optdepends, 
_alpm_optdep_dup(i->data));
+       }
        for(i = pkg->conflicts; i; i = i->next) {
                newpkg->conflicts = alpm_list_add(newpkg->conflicts, 
_alpm_dep_dup(i->data));
        }
@@ -593,7 +595,8 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
        alpm_list_free(pkg->backup);
        alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
        alpm_list_free(pkg->depends);
-       FREELIST(pkg->optdepends);
+       alpm_list_free_inner(pkg->optdepends, 
(alpm_list_fn_free)_alpm_optdep_free);
+       alpm_list_free(pkg->optdepends);
        alpm_list_free_inner(pkg->conflicts, (alpm_list_fn_free)_alpm_dep_free);
        alpm_list_free(pkg->conflicts);
        alpm_list_free_inner(pkg->provides, (alpm_list_fn_free)_alpm_dep_free);
diff --git a/src/pacman/package.c b/src/pacman/package.c
index d4bbf88..c7bfb14 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -40,7 +40,6 @@
 
 /** Turn a depends list into a text list.
  * @param deps a list with items of type alpm_depend_t
- * @return a string list, must be freed
  */
 static void deplist_display(const char *title,
                alpm_list_t *deps)
@@ -54,6 +53,21 @@ static void deplist_display(const char *title,
        FREELIST(text);
 }
 
+/** Turn a optdepends list into a text list.
+ * @param optdeps a list with items of type alpm_optdepend_t
+ */
+static void optdeplist_display(const char *title,
+               alpm_list_t *optdeps)
+{
+       alpm_list_t *i, *text = NULL;
+       for(i = optdeps; i; i = alpm_list_next(i)) {
+               alpm_optdepend_t *optdep = i->data;
+               text = alpm_list_add(text, alpm_optdep_compute_string(optdep));
+       }
+       list_display_linebreak(title, text);
+       FREELIST(text);
+}
+
 /**
  * Display the details of a package.
  * Extra information entails 'required by' info for sync packages and backup
@@ -113,7 +127,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
        list_display(_("Groups         :"), alpm_pkg_get_groups(pkg));
        deplist_display(_("Provides       :"), alpm_pkg_get_provides(pkg));
        deplist_display(_("Depends On     :"), alpm_pkg_get_depends(pkg));
-       list_display_linebreak(_("Optional Deps  :"), 
alpm_pkg_get_optdepends(pkg));
+       optdeplist_display(_("Optional Deps  :"), alpm_pkg_get_optdepends(pkg));
        if(extra || from == PKG_FROM_LOCALDB) {
                list_display(_("Required By    :"), requiredby);
        }
diff --git a/src/pacman/util.c b/src/pacman/util.c
index c0dcb9f..2363e6f 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -1139,32 +1139,81 @@ void print_packages(const alpm_list_t *packages)
        }
 }
 
-/* Helper function for comparing strings using the
- * alpm "compare func" signature */
-int str_cmp(const void *s1, const void *s2)
+/* Helper function for comparing optdepends using the
+ * alpm "compare func" signature. */
+static int opt_cmp(const void *o1, const void *o2)
 {
-       return strcmp(s1, s2);
+       const alpm_optdepend_t *od1 = o1;
+       const alpm_optdepend_t *od2 = o2;
+       int ret;
+
+       ret = strcmp(od1->depend->name, od2->depend->name);
+       if(ret == 0) {
+               ret = od1->depend->mod - od2->depend->mod;
+       }
+       if(ret == 0 && od1->depend->version != od2->depend->version) {
+               if(od1->depend->version && od2->depend->version) {
+                       ret = strcmp(od1->depend->version, 
od2->depend->version);
+               } else if(!od1->depend->version && od2->depend->version) {
+                       return -1;
+               } else if(od1->depend->version && !od2->depend->version) {
+                       return  1;
+               }
+       }
+       if(ret == 0 && od1->description != od2->description) {
+               if(od1->description && od2->description) {
+                       ret = strcmp(od1->description, od2->description);
+               } else if(!od1->description && od2->description) {
+                       return -1;
+               } else if(od1->description && !od2->description) {
+                       return  1;
+               }
+       }
+
+       return ret;
 }
 
 void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
 {
-       alpm_list_t *old = alpm_pkg_get_optdepends(oldpkg);
-       alpm_list_t *new = alpm_pkg_get_optdepends(newpkg);
-       alpm_list_t *optdeps = alpm_list_diff(new,old,str_cmp);
-       if(optdeps) {
+       alpm_list_t *i, *old, *new, *optdeps, *optstrings = NULL;
+
+       old = alpm_pkg_get_optdepends(oldpkg);
+       new = alpm_pkg_get_optdepends(newpkg);
+       optdeps = alpm_list_diff(new, old, opt_cmp);
+
+       /* turn optdepends list into a text list */
+       for(i = optdeps; i; i = alpm_list_next(i)) {
+               alpm_optdepend_t *optdep = i->data;
+               optstrings = alpm_list_add(optstrings, 
alpm_optdep_compute_string(optdep));
+       }
+
+       if(optstrings) {
                printf(_("New optional dependencies for %s\n"), 
alpm_pkg_get_name(newpkg));
-               list_display_linebreak("   ", optdeps);
+               list_display_linebreak("   ", optstrings);
        }
+
        alpm_list_free(optdeps);
+       FREELIST(optstrings);
 }
 
 void display_optdepends(alpm_pkg_t *pkg)
 {
-       alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
-       if(optdeps) {
+       alpm_list_t *i, *optdeps, *optstrings = NULL;
+
+       optdeps = alpm_pkg_get_optdepends(pkg);
+
+       /* turn optdepends list into a text list */
+       for(i = optdeps; i; i = alpm_list_next(i)) {
+               alpm_optdepend_t *optdep = i->data;
+               optstrings = alpm_list_add(optstrings, 
alpm_optdep_compute_string(optdep));
+       }
+
+       if(optstrings) {
                printf(_("Optional dependencies for %s\n"), 
alpm_pkg_get_name(pkg));
-               list_display_linebreak("   ", optdeps);
+               list_display_linebreak("   ", optstrings);
        }
+
+       FREELIST(optstrings);
 }
 
 static void display_repo_list(const char *dbname, alpm_list_t *list)
-- 
1.7.7.3


Reply via email to