No new behaviour introduced, everything should work exactly as before. Signed-off-by: Benedikt Morbach <benedikt.morbach@googlemail.com> --- lib/libalpm/be_local.c | 11 ++++++- lib/libalpm/be_package.c | 5 ++- lib/libalpm/be_sync.c | 7 ++++- lib/libalpm/package.c | 7 +++- src/pacman/package.c | 11 ++++++- src/pacman/util.c | 73 ++++++++++++++++++++++++++++++++++++++------- 6 files changed, 93 insertions(+), 21 deletions(-) diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 261ad87..401bc64 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -610,7 +610,12 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) info->depends = alpm_list_add(info->depends, _alpm_splitdep(line)); } } else if(strcmp(line, "%OPTDEPENDS%") == 0) { - READ_AND_STORE_ALL(info->optdepends); + /* Different than the rest because of the _alpm_splitoptdep call. */ + while(1) { + READ_NEXT(); + if(strlen(line) == 0) break; + info->optdepends = alpm_list_add(info->optdepends, _alpm_splitoptdep(line)); + } } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_STORE_ALL(info->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { @@ -822,7 +827,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 0edaa5a..2cf3e46 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -35,7 +35,7 @@ #include "log.h" #include "handle.h" #include "package.h" -#include "deps.h" /* _alpm_splitdep */ +#include "deps.h" /** * Open a package changelog for reading. Similar to fopen in functionality, @@ -192,7 +192,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) { newpkg->conflicts = alpm_list_add(newpkg->conflicts, strdup(ptr)); } else if(strcmp(key, "replaces") == 0) { diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 07356f0..2b6f98e 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -555,7 +555,12 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive, pkg->depends = alpm_list_add(pkg->depends, _alpm_splitdep(line)); } } else if(strcmp(line, "%OPTDEPENDS%") == 0) { - READ_AND_STORE_ALL(pkg->optdepends); + /* Different than the rest because of the _alpm_splitoptdep call. */ + while(1) { + READ_NEXT(); + if(strlen(line) == 0) break; + pkg->optdepends = alpm_list_add(pkg->optdepends, _alpm_splitoptdep(line)); + } } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_STORE_ALL(pkg->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index fd3d0c6..1d30503 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -503,7 +503,9 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg) for(i = pkg->depends; i; i = alpm_list_next(i)) { 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 = alpm_list_next(i)) { + newpkg->optdepends = alpm_list_add(newpkg->optdepends, _alpm_optdep_dup(i->data)); + } newpkg->conflicts = alpm_list_strdup(pkg->conflicts); newpkg->provides = alpm_list_strdup(pkg->provides); for(i = pkg->deltas; i; i = alpm_list_next(i)) { @@ -557,7 +559,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); FREELIST(pkg->conflicts); FREELIST(pkg->provides); alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free); diff --git a/src/pacman/package.c b/src/pacman/package.c index 45afded..7b1442e 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -53,7 +53,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra) const char *label; double size; const alpm_list_t *i; - alpm_list_t *requiredby = NULL, *depstrings = NULL; + alpm_list_t *depstrings = NULL, *optstrings = NULL, *requiredby = NULL; if(pkg == NULL) { return; @@ -87,6 +87,12 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra) depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(dep)); } + /* turn optdepends list into a text list */ + for(i = alpm_pkg_get_optdepends(pkg); i; i = alpm_list_next(i)) { + alpm_optdepend_t *optdep = alpm_list_getdata(i); + optstrings = alpm_list_add(optstrings, alpm_optdep_compute_string(optdep)); + } + if(extra || from == PKG_FROM_LOCALDB) { /* compute this here so we don't get a pause in the middle of output */ requiredby = alpm_pkg_compute_requiredby(pkg); @@ -104,7 +110,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra) list_display(_("Groups :"), alpm_pkg_get_groups(pkg)); list_display(_("Provides :"), alpm_pkg_get_provides(pkg)); list_display(_("Depends On :"), depstrings); - list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg)); + list_display_linebreak(_("Optional Deps :"), optstrings); if(extra || from == PKG_FROM_LOCALDB) { list_display(_("Required By :"), requiredby); } @@ -158,6 +164,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra) printf("\n"); FREELIST(depstrings); + FREELIST(optstrings); FREELIST(requiredby); } diff --git a/src/pacman/util.c b/src/pacman/util.c index 7065abd..f66d6e1 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -974,32 +974,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 = alpm_list_getdata(i); + 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 = alpm_list_getdata(i); + 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.6