pkg: convert most other struct members into dynamic blob buffer fields
authorJo-Philipp Wich <jo@mein.io>
Sun, 12 Feb 2017 20:43:11 +0000 (21:43 +0100)
committerJo-Philipp Wich <jo@mein.io>
Mon, 13 Feb 2017 16:14:44 +0000 (17:14 +0100)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
libopkg/opkg_cmd.c
libopkg/opkg_install.c
libopkg/opkg_remove.c
libopkg/pkg.c
libopkg/pkg.h
libopkg/pkg_depends.c
libopkg/pkg_depends.h
libopkg/pkg_hash.c
libopkg/pkg_parse.c

index 7f51ea9..c50d8f9 100644 (file)
@@ -285,7 +285,6 @@ opkg_recurse_pkgs_in_order(pkg_t * pkg, pkg_vec_t * all,
                           pkg_vec_t * visited, pkg_vec_t * ordered)
 {
        int j, k, l, m;
-       int count;
        pkg_t *dep;
        compound_depend_t *compound_depend;
        depend_t **possible_satisfiers;
@@ -312,17 +311,13 @@ opkg_recurse_pkgs_in_order(pkg_t * pkg, pkg_vec_t * all,
 
        pkg_vec_insert(visited, pkg);
 
-       count = pkg->pre_depends_count + pkg->depends_count +
-           pkg->recommends_count + pkg->suggests_count;
-
        opkg_msg(DEBUG, "pkg %s.\n", pkg->name);
 
        /* Iterate over all the dependencies of pkg. For each one, find a package
           that is either installed or unpacked and satisfies this dependency.
           (there should only be one such package per dependency installed or
           unpacked). Then recurse to the dependency package */
-       for (j = 0; j < count; j++) {
-               compound_depend = &pkg->depends[j];
+       for (compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS); compound_depend && compound_depend->type; compound_depend++) {
                possible_satisfiers = compound_depend->possibilities;
                for (k = 0; k < compound_depend->possibility_count; k++) {
                        abpkg = possible_satisfiers[k]->pkg;
@@ -633,6 +628,7 @@ static int opkg_list_changed_conffiles_cmd(int argc, char **argv)
        pkg_t *pkg;
        char *pkg_name = NULL;
        conffile_list_elt_t *iter;
+       conffile_list_t *cl;
        conffile_t *cf;
 
        if (argc > 0) {
@@ -643,13 +639,14 @@ static int opkg_list_changed_conffiles_cmd(int argc, char **argv)
        pkg_vec_sort(available, pkg_compare_names);
        for (i = 0; i < available->len; i++) {
                pkg = available->pkgs[i];
+               cl = pkg_get_ptr(pkg, PKG_CONFFILES);
                /* if we have package name or pattern and pkg does not match, then skip it */
                if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
                        continue;
-               if (nv_pair_list_empty(&pkg->conffiles))
+               if (!cl || nv_pair_list_empty(cl))
                        continue;
-               for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-                    iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+               for (iter = nv_pair_list_first(cl); iter;
+                    iter = nv_pair_list_next(cl, iter)) {
                        cf = (conffile_t *) iter->data;
                        if (cf->name && cf->value
                            && conffile_has_been_modified(cf))
@@ -690,6 +687,7 @@ static int opkg_info_status_cmd(int argc, char **argv, int installed_only)
        pkg_vec_t *available;
        pkg_t *pkg;
        char *pkg_name = NULL;
+       conffile_list_t *cl;
 
        if (argc > 0) {
                pkg_name = argv[0];
@@ -709,10 +707,12 @@ static int opkg_info_status_cmd(int argc, char **argv, int installed_only)
 
                pkg_formatted_info(stdout, pkg);
 
-               if (conf->verbosity >= NOTICE) {
+               cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+               if (conf->verbosity >= NOTICE && cl) {
                        conffile_list_elt_t *iter;
-                       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-                            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+                       for (iter = nv_pair_list_first(cl); iter;
+                            iter = nv_pair_list_next(cl, iter)) {
                                conffile_t *cf = (conffile_t *) iter->data;
                                int modified = conffile_has_been_modified(cf);
                                if (cf->value)
@@ -897,7 +897,6 @@ static int opkg_files_cmd(int argc, char **argv)
 static int opkg_depends_cmd(int argc, char **argv)
 {
        int i, j, k;
-       int depends_count;
        pkg_vec_t *available_pkgs;
        compound_depend_t *cdep;
        pkg_t *pkg;
@@ -918,15 +917,9 @@ static int opkg_depends_cmd(int argc, char **argv)
                        if (fnmatch(argv[i], pkg->name, conf->nocase) != 0)
                                continue;
 
-                       depends_count = pkg->depends_count +
-                           pkg->pre_depends_count +
-                           pkg->recommends_count + pkg->suggests_count;
-
                        opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
 
-                       for (k = 0; k < depends_count; k++) {
-                               cdep = &pkg->depends[k];
-
+                       for (k = 0, cdep = pkg_get_ptr(pkg, PKG_DEPENDS); cdep && cdep->type; k++, cdep++) {
                                if (cdep->type != DEPEND)
                                        continue;
 
@@ -944,13 +937,15 @@ static int opkg_depends_cmd(int argc, char **argv)
 
 static int pkg_mark_provides(pkg_t * pkg)
 {
-       int provides_count = pkg->provides_count;
-       abstract_pkg_t **provides = pkg->provides;
-       int i;
+       abstract_pkg_t **provider = pkg_get_ptr(pkg, PKG_PROVIDES);
+
        pkg->parent->state_flag |= SF_MARKED;
-       for (i = 0; i < provides_count; i++) {
-               provides[i]->state_flag |= SF_MARKED;
+
+       while (provider && *provider) {
+               (*provider)->state_flag |= SF_MARKED;
+               provider++;
        }
+
        return 0;
 }
 
@@ -968,11 +963,11 @@ opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive,
                                int argc, char **argv)
 {
        depend_t *possibility;
-       compound_depend_t *cdep;
+       compound_depend_t *cdep, *deps;
        pkg_vec_t *available_pkgs;
        pkg_t *pkg;
-       int i, j, k, l;
-       int changed, count;
+       int i, j, l;
+       int changed;
        const char *rel_str = NULL;
        char *ver;
 
@@ -1022,21 +1017,21 @@ opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive,
                for (j = 0; j < available_pkgs->len; j++) {
 
                        pkg = available_pkgs->pkgs[j];
+                       /*
                        count = ((what_field_type == CONFLICTS)
                                 ? pkg->conflicts_count
                                 : pkg->pre_depends_count +
                                 pkg->depends_count +
                                 pkg->recommends_count + pkg->suggests_count);
+                                */
 
                        /* skip this package if it is already marked */
                        if (pkg->parent->state_flag & SF_MARKED)
                                continue;
 
-                       for (k = 0; k < count; k++) {
-                               cdep = (what_field_type == CONFLICTS)
-                                   ? &pkg->conflicts[k]
-                                   : &pkg->depends[k];
+                       deps = pkg_get_ptr(pkg, (what_field_type == CONFLICTS) ? PKG_CONFLICTS : PKG_DEPENDS);
 
+                       for (cdep = deps; cdep->type; cdep++) {
                                if (what_field_type != cdep->type)
                                        continue;
 
@@ -1115,6 +1110,7 @@ static int
 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc,
                                char **argv)
 {
+       abstract_pkg_t *apkg, **abpkgs;
 
        if (argc > 0) {
                pkg_vec_t *available_pkgs = pkg_vec_alloc();
@@ -1135,33 +1131,22 @@ opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc,
                        opkg_msg(NOTICE, "What %s %s\n", rel_str, target);
                        for (j = 0; j < available_pkgs->len; j++) {
                                pkg_t *pkg = available_pkgs->pkgs[j];
-                               int k;
-                               int count =
-                                   (what_field_type ==
-                                    WHATPROVIDES) ? pkg->provides_count : pkg->
-                                   replaces_count;
-                               for (k = 0; k < count; k++) {
-                                       abstract_pkg_t *apkg =
-                                           ((what_field_type == WHATPROVIDES)
-                                            ? pkg->provides[k]
-                                            : pkg->replaces[k]);
-                                       if (fnmatch
-                                           (target, apkg->name,
-                                            conf->nocase) == 0) {
-                                               opkg_msg(NOTICE, "    %s",
-                                                        pkg->name);
-                                               if ((conf->
-                                                    nocase ? strcasecmp(target,
-                                                                        apkg->
-                                                                        name) :
-                                                    strcmp(target,
-                                                           apkg->name)) != 0)
-                                                       opkg_msg(NOTICE,
-                                                                "\t%s %s\n",
-                                                                rel_str,
-                                                                apkg->name);
-                                               opkg_message(NOTICE, "\n");
-                                       }
+                               abpkgs = pkg_get_ptr(pkg, (what_field_type == WHATPROVIDES) ? PKG_PROVIDES : PKG_REPLACES);
+
+                               while (abpkgs && *abpkgs) {
+                                       apkg = *abpkgs;
+
+                                       if (fnmatch(target, apkg->name, conf->nocase))
+                                               continue;
+
+                                       opkg_msg(NOTICE, "    %s", pkg->name);
+
+                                       if ((conf->nocase ? strcasecmp(target, apkg->name)
+                                           : strcmp(target, apkg->name)))
+                                               opkg_msg(NOTICE, "\t%s %s\n", rel_str, apkg->name);
+
+                                       opkg_message(NOTICE, "\n");
+                                       abpkgs++;
                                }
                        }
                }
index 2d31905..55c124b 100644 (file)
@@ -232,19 +232,23 @@ static int unpack_pkg_control_files(pkg_t * pkg)
        int err;
        char *conffiles_file_name;
        char *root_dir;
+       char *tmp_unpack_dir;
        FILE *conffiles_file;
+       conffile_list_t *cl;
 
-       sprintf_alloc(&pkg->tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir,
+       sprintf_alloc(&tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir,
                      pkg->name);
 
-       pkg->tmp_unpack_dir = mkdtemp(pkg->tmp_unpack_dir);
-       if (pkg->tmp_unpack_dir == NULL) {
+       tmp_unpack_dir = mkdtemp(tmp_unpack_dir);
+       if (tmp_unpack_dir == NULL) {
                opkg_perror(ERROR, "Failed to create temporary directory '%s'",
-                           pkg->tmp_unpack_dir);
+                           tmp_unpack_dir);
                return -1;
        }
 
-       err = pkg_extract_control_files_to_dir(pkg, pkg->tmp_unpack_dir);
+       pkg_set_string(pkg, PKG_TMP_UNPACK_DIR, tmp_unpack_dir);
+
+       err = pkg_extract_control_files_to_dir(pkg, tmp_unpack_dir);
        if (err) {
                return err;
        }
@@ -255,12 +259,13 @@ static int unpack_pkg_control_files(pkg_t * pkg)
           move all of unpack_pkg_control_files to that function. */
 
        /* Don't need to re-read conffiles if we already have it */
-       if (!nv_pair_list_empty(&pkg->conffiles)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+       if (cl && !nv_pair_list_empty(cl)) {
                return 0;
        }
 
        sprintf_alloc(&conffiles_file_name, "%s/conffiles",
-                     pkg->tmp_unpack_dir);
+                     tmp_unpack_dir);
        if (!file_exists(conffiles_file_name)) {
                free(conffiles_file_name);
                return 0;
@@ -274,6 +279,9 @@ static int unpack_pkg_control_files(pkg_t * pkg)
        }
        free(conffiles_file_name);
 
+       cl = xcalloc(1, sizeof(*cl));
+       conffile_list_init(cl);
+
        while (1) {
                char *cf_name;
                char *cf_name_in_dest;
@@ -304,12 +312,14 @@ static int unpack_pkg_control_files(pkg_t * pkg)
 
                /* Can't get an md5sum now, (file isn't extracted yet).
                   We'll wait until resolve_conffiles */
-               conffile_list_append(&pkg->conffiles, cf_name_in_dest, NULL);
+               conffile_list_append(cl, cf_name_in_dest, NULL);
 
                free(cf_name);
                free(cf_name_in_dest);
        }
 
+       pkg_set_ptr(pkg, PKG_CONFFILES, cl);
+
        fclose(conffiles_file);
 
        return 0;
@@ -321,28 +331,20 @@ static int unpack_pkg_control_files(pkg_t * pkg)
  */
 static int pkg_remove_orphan_dependent(pkg_t * pkg, pkg_t * old_pkg)
 {
-       int i, j, k, l, found, r, err = 0;
+       int j, l, found, r, err = 0;
        int n_deps;
        pkg_t *p;
        struct compound_depend *cd0, *cd1;
        abstract_pkg_t **dependents;
 
-       int count0 = old_pkg->pre_depends_count +
-           old_pkg->depends_count +
-           old_pkg->recommends_count + old_pkg->suggests_count;
-       int count1 = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
-
-       for (i = 0; i < count0; i++) {
-               cd0 = &old_pkg->depends[i];
+       for (cd0 = pkg_get_ptr(old_pkg, PKG_DEPENDS); cd0 && cd0->type; cd0++) {
                if (cd0->type != DEPEND)
                        continue;
                for (j = 0; j < cd0->possibility_count; j++) {
 
                        found = 0;
 
-                       for (k = 0; k < count1; k++) {
-                               cd1 = &pkg->depends[k];
+                       for (cd1 = pkg_get_ptr(pkg, PKG_DEPENDS); cd1 && cd1->type; cd1++) {
                                if (cd1->type != DEPEND)
                                        continue;
                                for (l = 0; l < cd1->possibility_count; l++) {
@@ -402,11 +404,11 @@ static int pkg_remove_orphan_dependent(pkg_t * pkg, pkg_t * old_pkg)
 static int
 pkg_get_installed_replacees(pkg_t * pkg, pkg_vec_t * installed_replacees)
 {
-       abstract_pkg_t **replaces = pkg->replaces;
-       int replaces_count = pkg->replaces_count;
-       int i, j;
-       for (i = 0; i < replaces_count; i++) {
-               abstract_pkg_t *ab_pkg = replaces[i];
+       abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
+       int j;
+
+       while (replaces && *replaces) {
+               abstract_pkg_t *ab_pkg = *replaces++;
                pkg_vec_t *pkg_vec = ab_pkg->pkgs;
                if (pkg_vec) {
                        for (j = 0; j < pkg_vec->len; j++) {
@@ -420,6 +422,7 @@ pkg_get_installed_replacees(pkg_t * pkg, pkg_vec_t * installed_replacees)
                        }
                }
        }
+
        return installed_replacees->len;
 }
 
@@ -692,14 +695,17 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg)
        int err;
        conffile_list_elt_t *iter;
        conffile_t *cf;
+       conffile_list_t *cl;
 
        if (conf->noaction)
                return 0;
 
        /* Backup all modified conffiles */
        if (old_pkg) {
-               for (iter = nv_pair_list_first(&old_pkg->conffiles); iter;
-                    iter = nv_pair_list_next(&old_pkg->conffiles, iter)) {
+               cl = pkg_get_ptr(old_pkg, PKG_CONFFILES);
+
+               for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+                    iter = nv_pair_list_next(cl, iter)) {
                        char *cf_name;
 
                        cf = iter->data;
@@ -718,8 +724,10 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg)
        }
 
        /* Backup all conffiles that were not conffiles in old_pkg */
-       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+            iter = nv_pair_list_next(cl, iter)) {
                char *cf_name;
                cf = (conffile_t *) iter->data;
                cf_name = root_filename_alloc(cf->name);
@@ -742,17 +750,22 @@ static int backup_modified_conffiles(pkg_t * pkg, pkg_t * old_pkg)
 
 static int backup_modified_conffiles_unwind(pkg_t * pkg, pkg_t * old_pkg)
 {
+       conffile_list_t *cl;
        conffile_list_elt_t *iter;
 
        if (old_pkg) {
-               for (iter = nv_pair_list_first(&old_pkg->conffiles); iter;
-                    iter = nv_pair_list_next(&old_pkg->conffiles, iter)) {
+               cl = pkg_get_ptr(old_pkg, PKG_CONFFILES);
+
+               for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+                    iter = nv_pair_list_next(cl, iter)) {
                        backup_remove(((nv_pair_t *) iter->data)->name);
                }
        }
 
-       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+            iter = nv_pair_list_next(cl, iter)) {
                backup_remove(((nv_pair_t *) iter->data)->name);
        }
 
@@ -1108,6 +1121,7 @@ static int install_data_files(pkg_t * pkg)
 static int resolve_conffiles(pkg_t * pkg)
 {
        conffile_list_elt_t *iter;
+       conffile_list_t *cl;
        conffile_t *cf;
        char *cf_backup;
        char *chksum;
@@ -1115,8 +1129,10 @@ static int resolve_conffiles(pkg_t * pkg)
        if (conf->noaction)
                return 0;
 
-       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+            iter = nv_pair_list_next(cl, iter)) {
                char *root_filename;
                cf = (conffile_t *) iter->data;
                root_filename = root_filename_alloc(cf->name);
@@ -1330,6 +1346,8 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade)
                                 pkg->name);
                        return -1;
                }
+
+               local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME);
        }
 
        /* check that the repository is valid */
@@ -1423,7 +1441,7 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade)
                return 0;
        }
 
-       if (pkg->tmp_unpack_dir == NULL) {
+       if (!pkg_get_string(pkg, PKG_TMP_UNPACK_DIR)) {
                if (unpack_pkg_control_files(pkg) == -1) {
                        opkg_msg(ERROR,
                                 "Failed to unpack control files from %s.\n",
index 41d98d9..694c3f3 100644 (file)
  */
 int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents)
 {
-       int nprovides = pkg->provides_count;
-       abstract_pkg_t **provides = pkg->provides;
-       unsigned int n_installed_dependents = 0;
-       int i;
-       for (i = 0; i < nprovides; i++) {
-               abstract_pkg_t *providee = provides[i];
+       abstract_pkg_t **provider, **provides = pkg_get_ptr(pkg, PKG_PROVIDES);
+       unsigned int i, n_installed_dependents = 0;
+
+       provider = provides;
+
+       while (provider && *provider) {
+               abstract_pkg_t *providee = *provider++;
                abstract_pkg_t **dependers = providee->depended_upon_by;
                abstract_pkg_t *dep_ab_pkg;
                if (dependers == NULL)
@@ -47,8 +48,8 @@ int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents)
                                n_installed_dependents++;
                        }
                }
-
        }
+
        /* if caller requested the set of installed dependents */
        if (pdependents) {
                int p = 0;
@@ -56,9 +57,11 @@ int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents)
                    xcalloc((n_installed_dependents + 1),
                            sizeof(abstract_pkg_t *));
 
+               provider = provides;
                *pdependents = dependents;
-               for (i = 0; i < nprovides; i++) {
-                       abstract_pkg_t *providee = provides[i];
+
+               while (provider && *provider) {
+                       abstract_pkg_t *providee = *provider++;
                        abstract_pkg_t **dependers = providee->depended_upon_by;
                        abstract_pkg_t *dep_ab_pkg;
                        if (dependers == NULL)
@@ -169,18 +172,14 @@ static void print_dependents_warning(pkg_t * pkg, abstract_pkg_t ** dependents)
  */
 static int remove_autoinstalled(pkg_t * pkg)
 {
-       int i, j;
+       int j;
        int err = 0;
        int n_deps;
        pkg_t *p;
        struct compound_depend *cdep;
        abstract_pkg_t **dependents;
 
-       int count = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
-
-       for (i = 0; i < count; i++) {
-               cdep = &pkg->depends[i];
+       for (cdep = pkg_get_ptr(pkg, PKG_DEPENDS); cdep && cdep->type; cdep++) {
                if (cdep->type != PREDEPEND
                    && cdep->type != DEPEND && cdep->type != RECOMMEND)
                        continue;
index 7b10c1a..2a393a7 100644 (file)
@@ -79,29 +79,9 @@ static void pkg_init(pkg_t * pkg)
        pkg->state_want = SW_UNKNOWN;
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
-       pkg->depends_str = NULL;
-       pkg->provides_str = NULL;
-       pkg->depends_count = 0;
-       pkg->depends = NULL;
-       pkg->suggests_str = NULL;
-       pkg->recommends_str = NULL;
-       pkg->suggests_count = 0;
-       pkg->recommends_count = 0;
 
        active_list_init(&pkg->list);
 
-       pkg->conflicts = NULL;
-       pkg->conflicts_count = 0;
-
-       pkg->replaces = NULL;
-       pkg->replaces_count = 0;
-
-       pkg->pre_depends_count = 0;
-       pkg->pre_depends_str = NULL;
-       pkg->provides_count = 0;
-       pkg->provides = NULL;
-       pkg->tmp_unpack_dir = NULL;
-       conffile_list_init(&pkg->conffiles);
        pkg->installed_files = NULL;
        pkg->installed_files_ref_cnt = 0;
        pkg->essential = 0;
@@ -194,7 +174,7 @@ static void compound_depend_deinit(compound_depend_t * depends)
 
 void pkg_deinit(pkg_t * pkg)
 {
-       int i;
+       compound_depend_t *deps, *dep;
 
        if (pkg->name)
                free(pkg->name);
@@ -211,40 +191,27 @@ void pkg_deinit(pkg_t * pkg)
 
        active_list_clear(&pkg->list);
 
-       if (pkg->replaces)
-               free(pkg->replaces);
-       pkg->replaces = NULL;
+       deps = pkg_get_ptr(pkg, PKG_DEPENDS);
 
-       if (pkg->depends) {
-               int count = pkg->pre_depends_count
-                   + pkg->depends_count
-                   + pkg->recommends_count + pkg->suggests_count;
-
-               for (i = 0; i < count; i++)
-                       compound_depend_deinit(&pkg->depends[i]);
-               free(pkg->depends);
-       }
+       if (deps) {
+               for (dep = deps; dep->type; dep++)
+                       compound_depend_deinit(dep);
 
-       if (pkg->conflicts) {
-               for (i = 0; i < pkg->conflicts_count; i++)
-                       compound_depend_deinit(&pkg->conflicts[i]);
-               free(pkg->conflicts);
+               free(deps);
+               pkg_set_ptr(pkg, PKG_DEPENDS, NULL);
        }
 
-       if (pkg->provides)
-               free(pkg->provides);
+       deps = pkg_get_ptr(pkg, PKG_CONFLICTS);
 
-       pkg->pre_depends_count = 0;
-       pkg->provides_count = 0;
+       if (deps) {
+               for (dep = deps; dep->type; dep++)
+                       compound_depend_deinit(dep);
 
-       /* CLEANUP: It'd be nice to pullin the cleanup function from
-          opkg_install.c here. See comment in
-          opkg_install.c:cleanup_temporary_files */
-       if (pkg->tmp_unpack_dir)
-               free(pkg->tmp_unpack_dir);
-       pkg->tmp_unpack_dir = NULL;
+               free(deps);
+               pkg_set_ptr(pkg, PKG_CONFLICTS, NULL);
+       }
 
-       conffile_list_deinit(&pkg->conffiles);
+       //conffile_list_deinit(&pkg->conffiles);
 
        /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
           since if they are calling deinit, they should know. Maybe do an
@@ -253,7 +220,7 @@ void pkg_deinit(pkg_t * pkg)
        pkg_free_installed_files(pkg);
        pkg->essential = 0;
 
-       blob_buf_free(&pkg->blob);
+       //blob_buf_free(&pkg->blob);
 }
 
 int pkg_init_from_file(pkg_t * pkg, const char *filename)
@@ -315,6 +282,9 @@ err0:
 /* Merge any new information in newpkg into oldpkg */
 int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
 {
+       abstract_pkg_t **ab;
+       conffile_list_t *cf, head;
+
        if (oldpkg == newpkg) {
                return 0;
        }
@@ -328,8 +298,8 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                oldpkg->dest = newpkg->dest;
        if (!pkg_get_string(oldpkg, PKG_ARCHITECTURE))
                pkg_set_string(oldpkg, PKG_ARCHITECTURE, pkg_get_string(newpkg, PKG_ARCHITECTURE));
-       if (!oldpkg->arch_priority)
-               oldpkg->arch_priority = newpkg->arch_priority;
+       if (!pkg_get_int(oldpkg, PKG_ARCH_PRIORITY))
+               pkg_set_int(oldpkg, PKG_ARCH_PRIORITY, pkg_get_int(newpkg, PKG_ARCH_PRIORITY));
        if (!pkg_get_string(oldpkg, PKG_SECTION))
                pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION));
        if (!pkg_get_string(oldpkg, PKG_MAINTAINER))
@@ -337,56 +307,34 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
        if (!pkg_get_string(oldpkg, PKG_DESCRIPTION))
                pkg_set_string(oldpkg, PKG_DESCRIPTION, pkg_get_string(newpkg, PKG_DESCRIPTION));
 
-       if (!oldpkg->depends_count && !oldpkg->pre_depends_count
-           && !oldpkg->recommends_count && !oldpkg->suggests_count) {
-               oldpkg->depends_count = newpkg->depends_count;
-               newpkg->depends_count = 0;
-
-               oldpkg->depends = newpkg->depends;
-               newpkg->depends = NULL;
-
-               oldpkg->pre_depends_count = newpkg->pre_depends_count;
-               newpkg->pre_depends_count = 0;
-
-               oldpkg->recommends_count = newpkg->recommends_count;
-               newpkg->recommends_count = 0;
-
-               oldpkg->suggests_count = newpkg->suggests_count;
-               newpkg->suggests_count = 0;
+       if (!pkg_get_ptr(oldpkg, PKG_DEPENDS)) {
+               pkg_set_ptr(oldpkg, PKG_DEPENDS, pkg_get_ptr(newpkg, PKG_DEPENDS));
+               pkg_set_ptr(newpkg, PKG_DEPENDS, NULL);
        }
 
-       if (oldpkg->provides_count <= 1) {
-               oldpkg->provides_count = newpkg->provides_count;
-               newpkg->provides_count = 0;
+       ab = pkg_get_ptr(oldpkg, PKG_PROVIDES);
 
-               if (!oldpkg->provides) {
-                       oldpkg->provides = newpkg->provides;
-                       newpkg->provides = NULL;
-               }
+       if (!ab || !ab[0] || !ab[1]) {
+               pkg_set_ptr(oldpkg, PKG_PROVIDES, pkg_get_ptr(newpkg, PKG_PROVIDES));
+               pkg_set_ptr(newpkg, PKG_PROVIDES, NULL);
        }
 
-       if (!oldpkg->conflicts_count) {
-               oldpkg->conflicts_count = newpkg->conflicts_count;
-               newpkg->conflicts_count = 0;
-
-               oldpkg->conflicts = newpkg->conflicts;
-               newpkg->conflicts = NULL;
+       if (!pkg_get_ptr(oldpkg, PKG_CONFLICTS)) {
+               pkg_set_ptr(oldpkg, PKG_CONFLICTS, pkg_get_ptr(newpkg, PKG_CONFLICTS));
+               pkg_set_ptr(newpkg, PKG_CONFLICTS, NULL);
        }
 
-       if (!oldpkg->replaces_count) {
-               oldpkg->replaces_count = newpkg->replaces_count;
-               newpkg->replaces_count = 0;
-
-               oldpkg->replaces = newpkg->replaces;
-               newpkg->replaces = NULL;
+       if (!pkg_get_ptr(oldpkg, PKG_REPLACES)) {
+               pkg_set_ptr(oldpkg, PKG_REPLACES, pkg_get_ptr(newpkg, PKG_REPLACES));
+               pkg_set_ptr(newpkg, PKG_REPLACES, NULL);
        }
 
        if (!pkg_get_string(oldpkg, PKG_FILENAME))
                pkg_set_string(oldpkg, PKG_FILENAME, pkg_get_string(newpkg, PKG_FILENAME));
        if (!pkg_get_string(oldpkg, PKG_LOCAL_FILENAME))
                pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
-       if (!oldpkg->tmp_unpack_dir)
-               oldpkg->tmp_unpack_dir = xstrdup(newpkg->tmp_unpack_dir);
+       if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR))
+               pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR));
        if (!pkg_get_string(oldpkg, PKG_MD5SUM))
                pkg_set_string(oldpkg, PKG_MD5SUM, pkg_get_string(newpkg, PKG_MD5SUM));
        if (!pkg_get_string(oldpkg, PKG_SHA256SUM))
@@ -400,9 +348,13 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
        if (!pkg_get_string(oldpkg, PKG_SOURCE))
                pkg_set_string(oldpkg, PKG_SOURCE, pkg_get_string(newpkg, PKG_SOURCE));
 
-       if (nv_pair_list_empty(&oldpkg->conffiles)) {
-               list_splice_init(&newpkg->conffiles.head,
-                                &oldpkg->conffiles.head);
+       if (!pkg_get_ptr(oldpkg, PKG_CONFFILES)) {
+               cf = pkg_get_ptr(newpkg, PKG_CONFFILES);
+               if (cf) {
+                       conffile_list_init(&head);
+                       list_splice_init(&cf->head, &head.head);
+                       pkg_set_raw(oldpkg, PKG_CONFFILES, &head, sizeof(head));
+               }
        }
 
        if (!oldpkg->installed_files) {
@@ -585,8 +537,8 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        int i, j;
        char *str;
        const char *p;
-       int depends_count = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
+       compound_depend_t *dep;
+       abstract_pkg_t **ab_pkg;
 
        if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
                goto UNKNOWN_FMT_FIELD;
@@ -611,14 +563,17 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'c':
        case 'C':
                if (strcasecmp(field, "Conffiles") == 0) {
+                       conffile_list_t *cl;
                        conffile_list_elt_t *iter;
 
-                       if (nv_pair_list_empty(&pkg->conffiles))
+                       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+                       if (!cl || nv_pair_list_empty(cl))
                                return;
 
                        fprintf(fp, "Conffiles:\n");
-                       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-                            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+                       for (iter = nv_pair_list_first(cl); iter;
+                            iter = nv_pair_list_next(cl, iter)) {
                                if (((conffile_t *) iter->data)->name
                                    && ((conffile_t *) iter->data)->value) {
                                        fprintf(fp, " %s %s\n",
@@ -630,11 +585,12 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                        }
                } else if (strcasecmp(field, "Conflicts") == 0) {
                        struct depend *cdep;
-                       if (pkg->conflicts_count) {
+                       compound_depend_t *deps, *dep;
+                       deps = pkg_get_ptr(pkg, PKG_CONFLICTS);
+                       if (deps) {
                                fprintf(fp, "Conflicts:");
-                               for (i = 0; i < pkg->conflicts_count; i++) {
-                                       cdep =
-                                           pkg->conflicts[i].possibilities[0];
+                               for (i = 0, dep = deps; dep->type; dep++, i++) {
+                                       cdep = dep->possibilities[0];
                                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
                                                cdep->pkg->name);
                                        if (cdep->version) {
@@ -653,10 +609,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'd':
        case 'D':
                if (strcasecmp(field, "Depends") == 0) {
-                       if (pkg->depends_count) {
+                       dep = pkg_get_depends(pkg, DEPEND);
+                       if (dep) {
                                fprintf(fp, "Depends:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != DEPEND)
+                               for (i = 0, j = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != DEPEND)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -725,11 +682,13 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                } else if (strcasecmp(field, "Priority") == 0) {
                        fprintf(fp, "Priority: %s\n", pkg_get_string(pkg, PKG_PRIORITY));
                } else if (strcasecmp(field, "Provides") == 0) {
-                       if (pkg->provides_count > 1) {
+                       ab_pkg = pkg_get_ptr(pkg, PKG_PROVIDES);
+                       if (ab_pkg && ab_pkg[0] && ab_pkg[1]) {
                                fprintf(fp, "Provides:");
-                               for (i = 1; i < pkg->provides_count; i++) {
-                                       fprintf(fp, "%s %s", i == 1 ? "" : ",",
-                                               pkg->provides[i]->name);
+                               for (i = 0, ab_pkg++; *ab_pkg; i++, ab_pkg++) {
+                                       fprintf(fp, "%s %s", i == 0 ? "" : ",",
+                                               (*ab_pkg)->name);
+                                       ab_pkg++;
                                }
                                fprintf(fp, "\n");
                        }
@@ -740,19 +699,21 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'r':
        case 'R':
                if (strcasecmp(field, "Replaces") == 0) {
-                       if (pkg->replaces_count) {
+                       ab_pkg = pkg_get_ptr(pkg, PKG_REPLACES);
+                       if (ab_pkg && *ab_pkg) {
                                fprintf(fp, "Replaces:");
-                               for (i = 0; i < pkg->replaces_count; i++) {
+                               for (i = 0; *ab_pkg; i++, ab_pkg++) {
                                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
-                                               pkg->replaces[i]->name);
+                                               (*ab_pkg)->name);
                                }
                                fprintf(fp, "\n");
                        }
                } else if (strcasecmp(field, "Recommends") == 0) {
-                       if (pkg->recommends_count) {
+                       dep = pkg_get_depends(pkg, RECOMMEND);
+                       if (dep) {
                                fprintf(fp, "Recommends:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != RECOMMEND)
+                               for (j = 0, i = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != RECOMMEND)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -798,10 +759,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                                pkg_state_status_to_str(pkg->state_status));
                        free(pflag);
                } else if (strcasecmp(field, "Suggests") == 0) {
-                       if (pkg->suggests_count) {
+                       dep = pkg_get_depends(pkg, SUGGEST);
+                       if (dep) {
                                fprintf(fp, "Suggests:");
-                               for (j = 0, i = 0; i < depends_count; i++) {
-                                       if (pkg->depends[i].type != SUGGEST)
+                               for (j = 0, i = 0; dep && dep->type; i++, dep++) {
+                                       if (dep->type != SUGGEST)
                                                continue;
                                        str = pkg_depend_str(pkg, i);
                                        fprintf(fp, "%s %s", j == 0 ? "" : ",",
@@ -949,8 +911,8 @@ int pkg_compare_versions(const pkg_t * pkg, const pkg_t * ref_pkg)
 {
        unsigned int epoch1 = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
        unsigned int epoch2 = (unsigned int) pkg_get_int(ref_pkg, PKG_EPOCH);
-       char *revision1 = pkg_get_ptr(pkg, PKG_REVISION);
-       char *revision2 = pkg_get_ptr(ref_pkg, PKG_REVISION);
+       char *revision1 = pkg_get_string(pkg, PKG_REVISION);
+       char *revision2 = pkg_get_string(ref_pkg, PKG_REVISION);
        const char *version1 = pkg_get_string(pkg, PKG_VERSION);
        const char *version2 = pkg_get_string(ref_pkg, PKG_VERSION);
        int r;
@@ -1012,6 +974,7 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
        const pkg_t * b = *(const pkg_t **)p2;
        int namecmp;
        int vercmp;
+       int arch_prio1, arch_prio2;
        if (!a->name || !b->name) {
                opkg_msg(ERROR, "Internal error: a->name=%p, b->name=%p.\n",
                         a->name, b->name);
@@ -1024,15 +987,17 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
        vercmp = pkg_compare_versions(a, b);
        if (vercmp)
                return vercmp;
-       if (!a->arch_priority || !b->arch_priority) {
+       arch_prio1 = pkg_get_int(a, PKG_ARCH_PRIORITY);
+       arch_prio2 = pkg_get_int(b, PKG_ARCH_PRIORITY);
+       if (!arch_prio1 || !arch_prio2) {
                opkg_msg(ERROR,
                         "Internal error: a->arch_priority=%i b->arch_priority=%i.\n",
-                        a->arch_priority, b->arch_priority);
+                        arch_prio1, arch_prio2);
                return 0;
        }
-       if (a->arch_priority > b->arch_priority)
+       if (arch_prio1 > arch_prio2)
                return 1;
-       if (a->arch_priority < b->arch_priority)
+       if (arch_prio1 < arch_prio2)
                return -1;
        return 0;
 }
@@ -1055,7 +1020,7 @@ char *pkg_version_str_alloc(pkg_t * pkg)
        char *version, *revptr;
        unsigned int epoch = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
 
-       revptr = pkg_get_ptr(pkg, PKG_REVISION);
+       revptr = pkg_get_string(pkg, PKG_REVISION);
        verstr = pkg_get_string(pkg, PKG_VERSION);
 
        if (epoch) {
@@ -1242,14 +1207,17 @@ void pkg_remove_installed_files_list(pkg_t * pkg)
 conffile_t *pkg_get_conffile(pkg_t * pkg, const char *file_name)
 {
        conffile_list_elt_t *iter;
+       conffile_list_t *cl;
        conffile_t *conffile;
 
        if (pkg == NULL) {
                return NULL;
        }
 
-       for (iter = nv_pair_list_first(&pkg->conffiles); iter;
-            iter = nv_pair_list_next(&pkg->conffiles, iter)) {
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
+            iter = nv_pair_list_next(cl, iter)) {
                conffile = (conffile_t *) iter->data;
 
                if (strcmp(conffile->name, file_name) == 0) {
@@ -1265,6 +1233,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        int err;
        char *path;
        char *cmd;
+       char *tmp_unpack_dir;
 
        if (conf->noaction)
                return 0;
@@ -1278,7 +1247,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        }
 
        /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
-          have scripts in pkg->tmp_unpack_dir. */
+          have scripts in tmp_unpack_dir. */
        if (pkg->state_status == SS_INSTALLED
            || pkg->state_status == SS_UNPACKED) {
                if (pkg->dest == NULL) {
@@ -1289,13 +1258,14 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
                sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name,
                              script);
        } else {
-               if (pkg->tmp_unpack_dir == NULL) {
+               tmp_unpack_dir = pkg_get_string(pkg, PKG_TMP_UNPACK_DIR);
+               if (tmp_unpack_dir == NULL) {
                        opkg_msg(ERROR,
                                 "Internal error: %s has a NULL tmp_unpack_dir.\n",
                                 pkg->name);
                        return -1;
                }
-               sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
+               sprintf_alloc(&path, "%s/%s", tmp_unpack_dir, script);
        }
 
        opkg_msg(INFO, "Running script %s.\n", path);
index 0931e6e..7fdbea2 100644 (file)
@@ -90,12 +90,19 @@ enum pkg_fields {
        PKG_VERSION,
        PKG_REVISION,
        PKG_ARCHITECTURE,
+       PKG_ARCH_PRIORITY,
        PKG_DESCRIPTION,
        PKG_MD5SUM,
        PKG_SHA256SUM,
        PKG_SIZE,
        PKG_INSTALLED_SIZE,
        PKG_INSTALLED_TIME,
+       PKG_TMP_UNPACK_DIR,
+       PKG_REPLACES,
+       PKG_PROVIDES,
+       PKG_DEPENDS,
+       PKG_CONFLICTS,
+       PKG_CONFFILES,
 };
 
 struct abstract_pkg {
@@ -138,36 +145,13 @@ struct pkg {
        char *name;
        pkg_src_t *src;
        pkg_dest_t *dest;
-       pkg_state_want_t state_want;
-       pkg_state_flag_t state_flag;
-       pkg_state_status_t state_status;
-       char **depends_str;
-       unsigned int depends_count;
-       char **pre_depends_str;
-       unsigned int pre_depends_count;
-       char **recommends_str;
-       unsigned int recommends_count;
-       char **suggests_str;
-       unsigned int suggests_count;
+       pkg_state_want_t state_want:3;
+       pkg_state_flag_t state_flag:10;
+       pkg_state_status_t state_status:4;
        struct active_list list;        /* Used for installing|upgrading */
-       compound_depend_t *depends;
-
-       char **conflicts_str;
-       compound_depend_t *conflicts;
-       unsigned int conflicts_count;
-
-       char **replaces_str;
-       unsigned int replaces_count;
-       abstract_pkg_t **replaces;
-
-       char **provides_str;
-       unsigned int provides_count;
-       abstract_pkg_t **provides;
 
        abstract_pkg_t *parent;
 
-       char *tmp_unpack_dir;
-       conffile_list_t conffiles;
        /* As pointer for lazy evaluation */
        str_list_t *installed_files;
        /* XXX: CLEANUP: I'd like to perhaps come up with a better
@@ -175,7 +159,6 @@ struct pkg {
           installed_files list was being freed from an inner loop while
           still being used within an outer loop. */
        int installed_files_ref_cnt;
-       int arch_priority;
 
        int essential:1;
 /* Adding this flag, to "force" opkg to choose a "provided_by_hand" package, if there are multiple choice */
@@ -215,12 +198,13 @@ static inline char *pkg_get_string(const pkg_t *pkg, int id)
 
 static inline void * pkg_set_ptr(pkg_t *pkg, int id, void *ptr)
 {
-       return pkg_set_raw(pkg, id, ptr, sizeof(ptr));
+       return ptr ? *(void **) pkg_set_raw(pkg, id, &ptr, sizeof(ptr)) : NULL;
 }
 
 static inline void * pkg_get_ptr(const pkg_t *pkg, int id)
 {
-       return pkg_get_raw(pkg, id);
+       void **ptr = pkg_get_raw(pkg, id);
+       return ptr ? *ptr : NULL;
 }
 
 abstract_pkg_t *abstract_pkg_new(void);
index d741c4a..4ffe73a 100644 (file)
@@ -59,9 +59,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
 {
        pkg_t *satisfier_entry_pkg;
        int i, j, k;
-       int count, found;
+       int found;
        char **the_lost;
        abstract_pkg_t *ab_pkg;
+       compound_depend_t *compound_depend;
 
        /*
         * this is a setup to check for redundant/cyclic dependency checks,
@@ -78,11 +79,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
        } else {
                ab_pkg->dependencies_checked = 1;       /* mark it for subsequent visits */
        }
-        /**/
-           count =
-           pkg->pre_depends_count + pkg->depends_count +
-           pkg->recommends_count + pkg->suggests_count;
-       if (!count) {
+
+       compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS);
+
+       if (!compound_depend || !compound_depend->type) {
                *unresolved = NULL;
                return 0;
        }
@@ -90,8 +90,7 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
        the_lost = NULL;
 
        /* foreach dependency */
-       for (i = 0; i < count; i++) {
-               compound_depend_t *compound_depend = &pkg->depends[i];
+       for (; compound_depend && compound_depend->type; compound_depend++) {
                depend_t **possible_satisfiers =
                    compound_depend->possibilities;;
                found = 0;
@@ -322,34 +321,30 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
 */
 static int is_pkg_a_replaces(pkg_t * pkg_scout, pkg_t * pkg)
 {
-       int i;
-       int replaces_count = pkg->replaces_count;
-       abstract_pkg_t **replaces;
+       abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
 
-       if (pkg->replaces_count == 0)   // No replaces, it's surely a conflict
+       if (!replaces || !*replaces)
                return 0;
 
-       replaces = pkg->replaces;
-
-       for (i = 0; i < replaces_count; i++) {
-               if (strcmp(pkg_scout->name, pkg->replaces[i]->name) == 0) {     // Found
+       while (*replaces) {
+               if (strcmp(pkg_scout->name, (*replaces)->name) == 0) {  // Found
                        opkg_msg(DEBUG2, "Seems I've found a replace %s %s\n",
-                                pkg_scout->name, pkg->replaces[i]->name);
+                                pkg_scout->name, (*replaces)->name);
                        return 1;
                }
+               replaces++;
        }
-       return 0;
 
+       return 0;
 }
 
 pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg)
 {
        pkg_vec_t *installed_conflicts, *test_vec;
-       compound_depend_t *conflicts;
+       compound_depend_t *conflicts, *conflict;
        depend_t **possible_satisfiers;
        depend_t *possible_satisfier;
-       int i, j, k;
-       int count;
+       int j, k;
        abstract_pkg_t *ab_pkg;
        pkg_t **pkg_scouts;
        pkg_t *pkg_scout;
@@ -364,17 +359,14 @@ pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg)
                return (pkg_vec_t *) NULL;
        }
 
-       conflicts = pkg->conflicts;
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
        if (!conflicts) {
                return (pkg_vec_t *) NULL;
        }
        installed_conflicts = pkg_vec_alloc();
 
-       count = pkg->conflicts_count;
-
        /* foreach conflict */
-       for (i = 0; i < pkg->conflicts_count; i++) {
-
+       for (conflict = conflicts; conflict->type; conflict++ ) {
                possible_satisfiers = conflicts->possibilities;
 
                /* foreach possible satisfier */
@@ -537,17 +529,15 @@ static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg)
  */
 int pkg_replaces(pkg_t * pkg, pkg_t * replacee)
 {
-       abstract_pkg_t **replaces = pkg->replaces;
-       int replaces_count = pkg->replaces_count;
-       int replacee_provides_count = replacee->provides_count;
-       int i, j;
-       for (i = 0; i < replaces_count; i++) {
-               abstract_pkg_t *abstract_replacee = replaces[i];
-               for (j = 0; j < replacee_provides_count; j++) {
-                       if (replacee->provides[j] == abstract_replacee)
+       abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
+       abstract_pkg_t **provides = pkg_get_ptr(replacee, PKG_PROVIDES);
+       abstract_pkg_t **r, **p;
+
+       for (r = replaces; r && *r; r++)
+               for (p = provides; p && *p; p++)
+                       if (*r == *p)
                                return 1;
-               }
-       }
+
        return 0;
 }
 
@@ -557,12 +547,14 @@ int pkg_replaces(pkg_t * pkg, pkg_t * replacee)
  */
 int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee)
 {
-       compound_depend_t *conflicts = pkg->conflicts;
-       int conflicts_count = pkg->conflicts_count;
-       int i, j;
-       for (i = 0; i < conflicts_count; i++) {
-               int possibility_count = conflicts[i].possibility_count;
-               struct depend **possibilities = conflicts[i].possibilities;
+       compound_depend_t *conflicts, *conflict;
+
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
+
+       int j;
+       for (conflict = conflicts; conflict->type; conflict++) {
+               int possibility_count = conflict->possibility_count;
+               struct depend **possibilities = conflict->possibilities;
                for (j = 0; j < possibility_count; j++) {
                        if (possibilities[j]->pkg == conflictee) {
                                return 1;
@@ -578,22 +570,22 @@ int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee)
  */
 int pkg_conflicts(pkg_t * pkg, pkg_t * conflictee)
 {
-       compound_depend_t *conflicts = pkg->conflicts;
-       int conflicts_count = pkg->conflicts_count;
-       abstract_pkg_t **conflictee_provides = conflictee->provides;
-       int conflictee_provides_count = conflictee->provides_count;
-       int i, j, k;
+       int j;
        int possibility_count;
        struct depend **possibilities;
-       abstract_pkg_t *possibility;
+       compound_depend_t *conflicts, *conflict;
+       abstract_pkg_t **conflictee_provides, **provider, *possibility;
 
-       for (i = 0; i < conflicts_count; i++) {
-               possibility_count = conflicts[i].possibility_count;
-               possibilities = conflicts[i].possibilities;
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
+       conflictee_provides = pkg_get_ptr(conflictee, PKG_PROVIDES);
+
+       for (conflict = conflicts; conflict->type; conflict++) {
+               possibility_count = conflict->possibility_count;
+               possibilities = conflict->possibilities;
                for (j = 0; j < possibility_count; j++) {
                        possibility = possibilities[j]->pkg;
-                       for (k = 0; k < conflictee_provides_count; k++) {
-                               if (possibility == conflictee_provides[k]) {
+                       for (provider = conflictee_provides; provider && *provider; provider++) {
+                               if (possibility == *provider) {
                                        return 1;
                                }
                        }
@@ -647,8 +639,123 @@ char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx)
        return resized;
 }
 
+abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
+{
+       abstract_pkg_t *ab_pkg;
+       abstract_pkg_t **provides = pkg_get_ptr(pkg, PKG_PROVIDES);
+
+       if (!provides) {
+               provides = calloc(2, sizeof(abstract_pkg_t *));
+
+               if (!provides) {
+                       if (count)
+                               *count = 0;
+
+                       return NULL;
+               }
+
+               ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+               if (!ab_pkg->pkgs)
+                       ab_pkg->pkgs = pkg_vec_alloc();
+
+               abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
+
+               provides[0] = ab_pkg;
+               provides[1] = NULL;
+
+               if (count)
+                       *count = 2;
+
+               pkg_set_ptr(pkg, PKG_PROVIDES, provides);
+       }
+       else if (count) {
+               for (*count = 1; *provides; provides++)
+                       (*count)++;
+       }
+
+       return provides;
+}
+
+void parse_providelist(pkg_t *pkg, char *list)
+{
+       int count = 0;
+       char *item, *tok;
+       abstract_pkg_t *ab_pkg, *provided_abpkg, **tmp, **provides;
+
+       provides = init_providelist(pkg, &count);
+       ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+       if (!provides || !ab_pkg)
+               return;
+
+       for (item = strtok_r(list, ", ", &tok); item;
+            count++, item = strtok_r(NULL, ", ", &tok)) {
+               tmp = realloc(provides, sizeof(abstract_pkg_t *) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               provided_abpkg = ensure_abstract_pkg_by_name(item);
+
+               abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
+
+               provides = tmp;
+               provides[count - 1] = provided_abpkg;
+       }
+
+       provides[count - 1] = NULL;
+
+       pkg_set_ptr(pkg, PKG_PROVIDES, provides);
+}
+
+void parse_replacelist(pkg_t *pkg, char *list)
+{
+       int count;
+       char *item, *tok;
+       abstract_pkg_t *ab_pkg, *old_abpkg, **tmp, **replaces = NULL;
+
+       ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+       if (!ab_pkg->pkgs)
+               ab_pkg->pkgs = pkg_vec_alloc();
+
+       abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
+
+       for (count = 1, item = strtok_r(list, ", ", &tok);
+            item;
+            count++, item = strtok_r(NULL, ", ", &tok), count++) {
+               tmp = realloc(replaces, sizeof(abstract_pkg_t *) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               old_abpkg = ensure_abstract_pkg_by_name(item);
+
+               if (!old_abpkg->replaced_by)
+                       old_abpkg->replaced_by = abstract_pkg_vec_alloc();
+
+               /* if a package pkg both replaces and conflicts old_abpkg,
+                * then add it to the replaced_by vector so that old_abpkg
+                * will be upgraded to ab_pkg automatically */
+               if (pkg_conflicts_abstract(pkg, old_abpkg))
+                       abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg);
+
+               replaces = tmp;
+               replaces[count - 1] = old_abpkg;
+       }
+
+       if (!replaces)
+               return;
+
+       replaces[count - 1] = NULL;
+
+       pkg_set_ptr(pkg, PKG_REPLACES, replaces);
+}
+
 void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 {
+#if 0
        int i;
 
        /* every pkg provides itself */
@@ -668,12 +775,14 @@ void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
        }
        if (pkg->provides_str)
                free(pkg->provides_str);
+#endif
 }
 
 void buildConflicts(pkg_t * pkg)
 {
+       /*
        int i;
-       compound_depend_t *conflicts;
+       compound_depend_t *conflicts, *conflict;
 
        if (!pkg->conflicts_count)
                return;
@@ -688,10 +797,12 @@ void buildConflicts(pkg_t * pkg)
        }
        if (pkg->conflicts_str)
                free(pkg->conflicts_str);
+               */
 }
 
 void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 {
+#if 0
        int i;
 
        if (!pkg->replaces_count)
@@ -717,10 +828,62 @@ void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 
        if (pkg->replaces_str)
                free(pkg->replaces_str);
+#endif
+}
+
+void parse_deplist(pkg_t *pkg, enum depend_type type, char *list)
+{
+       int id, count;
+       char *item, *tok;
+       compound_depend_t *tmp, *deps;
+
+       switch (type)
+       {
+       case DEPEND:
+       case PREDEPEND:
+       case RECOMMEND:
+       case SUGGEST:
+       case GREEDY_DEPEND:
+               id = PKG_DEPENDS;
+               break;
+
+       case CONFLICTS:
+               id = PKG_CONFLICTS;
+               break;
+
+       default:
+               return;
+       }
+
+       deps = pkg_get_ptr(pkg, id);
+
+       for (tmp = deps, count = 1; tmp && tmp->type; tmp++)
+               count++;
+
+       for (item = strtok_r(list, ",", &tok); item; item = strtok_r(NULL, ",", &tok), count++) {
+               tmp = realloc(deps, sizeof(compound_depend_t) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               deps = tmp;
+
+               memset(deps + count - 1, 0, sizeof(compound_depend_t));
+               parseDepends(deps + count - 1, item);
+
+               deps[count - 1].type = type;
+       }
+
+       if (!deps)
+               return;
+
+       memset(deps + count - 1, 0, sizeof(compound_depend_t));
+       pkg_set_ptr(pkg, id, deps);
 }
 
 void buildDepends(pkg_t * pkg)
 {
+#if 0
        unsigned int count;
        int i;
        compound_depend_t *depends;
@@ -767,6 +930,8 @@ void buildDepends(pkg_t * pkg)
        }
        if (pkg->suggests_str)
                free(pkg->suggests_str);
+
+#endif
 }
 
 const char *constraint_to_str(enum version_constraint c)
@@ -798,11 +963,19 @@ char *pkg_depend_str(pkg_t * pkg, int idx)
        int i;
        unsigned int len;
        char *str;
-       compound_depend_t *cdep;
+       compound_depend_t *cdep = NULL, *p;
        depend_t *dep;
 
+       for (i = 0, p = pkg_get_ptr(pkg, PKG_DEPENDS); p && p->type; i++, p++)
+               if (i == idx) {
+                       cdep = p;
+                       break;
+               }
+
+       if (!cdep)
+               return NULL;
+
        len = 0;
-       cdep = &pkg->depends[idx];
 
        /* calculate string length */
        for (i = 0; i < cdep->possibility_count; i++) {
@@ -846,16 +1019,12 @@ char *pkg_depend_str(pkg_t * pkg, int idx)
 void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg)
 {
        compound_depend_t *depends;
-       int count, othercount;
-       int i, j;
+       int othercount;
+       int j;
        abstract_pkg_t *ab_depend;
        abstract_pkg_t **temp;
 
-       count = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
-
-       for (i = 0; i < count; i++) {
-               depends = &pkg->depends[i];
+       for (depends = pkg_get_ptr(pkg, PKG_DEPENDS); depends && depends->type; depends++) {
                if (depends->type != PREDEPEND
                    && depends->type != DEPEND && depends->type != RECOMMEND)
                        continue;
@@ -898,97 +1067,77 @@ static depend_t *depend_init(void)
 
 static int parseDepends(compound_depend_t * compound_depend, char *depend_str)
 {
-       char *pkg_name, buffer[2048];
-       unsigned int num_of_ors = 0;
        int i;
-       char *src, *dest;
-       depend_t **possibilities;
-
-       /* first count the number of ored possibilities for satisfying dependency */
-       src = depend_str;
-       while (*src)
-               if (*src++ == '|')
-                       num_of_ors++;
+       char *depend, *name, *vstr, *rest, *tok = NULL;
+       depend_t **possibilities = NULL, **tmp;
 
        compound_depend->type = DEPEND;
 
-       compound_depend->possibility_count = num_of_ors + 1;
-       possibilities = xcalloc((num_of_ors + 1), sizeof(depend_t *));
-       compound_depend->possibilities = possibilities;
+       for (i = 0, depend = strtok_r(depend_str, "|", &tok); depend; i++, depend = strtok_r(NULL, "|", &tok)) {
+               name = strtok(depend, " ");
+               rest = strtok(NULL, "\n");
+
+               tmp = realloc(possibilities, sizeof(tmp) * (i + 1));
 
-       src = depend_str;
-       for (i = 0; i < num_of_ors + 1; i++) {
+               if (!tmp)
+                       return -1;
+
+               possibilities = tmp;
                possibilities[i] = depend_init();
-               /* gobble up just the name first */
-               dest = buffer;
-               while (*src &&
-                      !isspace(*src) &&
-                      (*src != '(') && (*src != '*') && (*src != '|'))
-                       *dest++ = *src++;
-               *dest = '\0';
-               pkg_name = trim_xstrdup(buffer);
-
-               /* now look at possible version info */
-
-               /* skip to next chars */
-               if (isspace(*src))
-                       while (*src && isspace(*src))
-                               src++;
-
-               /* extract constraint and version */
-               if (*src == '(') {
-                       src++;
-                       if (!strncmp(src, "<<", 2)) {
+               possibilities[i]->pkg = ensure_abstract_pkg_by_name(name);
+
+               if (rest && *rest == '(') {
+                       vstr = strtok(rest + 1, ")");
+
+                       if (!strncmp(vstr, "<<", 2)) {
                                possibilities[i]->constraint = EARLIER;
-                               src += 2;
-                       } else if (!strncmp(src, "<=", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, "<=", 2)) {
                                possibilities[i]->constraint = EARLIER_EQUAL;
-                               src += 2;
-                       } else if (!strncmp(src, ">=", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, ">=", 2)) {
                                possibilities[i]->constraint = LATER_EQUAL;
-                               src += 2;
-                       } else if (!strncmp(src, ">>", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, ">>", 2)) {
                                possibilities[i]->constraint = LATER;
-                               src += 2;
-                       } else if (!strncmp(src, "=", 1)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, "=", 1)) {
                                possibilities[i]->constraint = EQUAL;
-                               src++;
+                               vstr++;
                        }
                        /* should these be here to support deprecated designations; dpkg does */
-                       else if (!strncmp(src, "<", 1)) {
+                       else if (!strncmp(vstr, "<", 1)) {
                                possibilities[i]->constraint = EARLIER_EQUAL;
-                               src++;
-                       } else if (!strncmp(src, ">", 1)) {
+                               vstr++;
+                       } else if (!strncmp(vstr, ">", 1)) {
                                possibilities[i]->constraint = LATER_EQUAL;
-                               src++;
+                               vstr++;
                        }
 
-                       /* now we have any constraint, pass space to version string */
-                       while (isspace(*src))
-                               src++;
-
-                       /* this would be the version string */
-                       dest = buffer;
-                       while (*src && *src != ')')
-                               *dest++ = *src++;
-                       *dest = '\0';
-
-                       possibilities[i]->version = trim_xstrdup(buffer);
+                       possibilities[i]->version = trim_xstrdup(vstr);
+                       rest = strtok(NULL, " ");
+               }
+               else {
+                       rest = strtok(rest, " ");
                }
-               /* hook up the dependency to its abstract pkg */
-               possibilities[i]->pkg = ensure_abstract_pkg_by_name(pkg_name);
-
-               free(pkg_name);
 
-               /* now get past the ) and any possible | chars */
-               while (*src &&
-                      (isspace(*src) || (*src == ')') || (*src == '|')))
-                       src++;
-               if (*src == '*') {
+               if (rest && *rest == '*')
                        compound_depend->type = GREEDY_DEPEND;
-                       src++;
-               }
        }
 
+       compound_depend->possibility_count = i;
+       compound_depend->possibilities = possibilities;
+
        return 0;
 }
+
+compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type)
+{
+       compound_depend_t *dep;
+
+       for (dep = pkg_get_ptr(pkg, PKG_DEPENDS); dep && dep->type; dep++)
+               if (type == UNSPEC || dep->type == type)
+                       return dep;
+
+       return NULL;
+}
index c1f7aa8..eeaa5ff 100644 (file)
@@ -22,6 +22,7 @@
 #include "pkg_hash.h"
 
 enum depend_type {
+       UNSPEC,
        PREDEPEND,
        DEPEND,
        CONFLICTS,
@@ -60,6 +61,11 @@ void buildConflicts(pkg_t * pkg);
 void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg);
 void buildDepends(pkg_t * pkg);
 
+void parse_deplist(pkg_t *pkg, enum depend_type type, char *list);
+
+abstract_pkg_t **init_providelist(pkg_t *pkg, int *count);
+void parse_providelist(pkg_t *pkg, char *list);
+
 /**
  * pkg_replaces returns 1 if pkg->replaces contains one of replacee's provides and 0
  * otherwise.
@@ -88,4 +94,6 @@ int pkg_dependence_satisfiable(depend_t * depend);
 int pkg_dependence_satisfied(depend_t * depend);
 const char *constraint_to_str(enum version_constraint c);
 
+compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type);
+
 #endif
index 1b3fd05..a8809a3 100644 (file)
@@ -141,7 +141,8 @@ pkg_hash_add_from_file(const char *file_name,
                        continue;
                }
 
-               if (!pkg_get_string(pkg, PKG_ARCHITECTURE) || !pkg->arch_priority) {
+               if (!pkg_get_string(pkg, PKG_ARCHITECTURE) ||
+                   !pkg_get_int(pkg, PKG_ARCH_PRIORITY)) {
                        char *version_str = pkg_version_str_alloc(pkg);
                        opkg_msg(NOTICE, "Package %s version %s has no "
                                 "valid architecture, ignoring.\n",
@@ -237,6 +238,7 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
        int nprovides = 0;
        int nmatching = 0;
        int wrong_arch_found = 0;
+       int arch_priority;
        pkg_vec_t *matching_pkgs;
        abstract_pkg_vec_t *matching_apkgs;
        abstract_pkg_vec_t *provided_apkg_vec;
@@ -317,13 +319,15 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                        /* count packages matching max arch priority and keep track of last one */
                        for (j = 0; j < vec->len; j++) {
                                pkg_t *maybe = vec->pkgs[j];
+                               arch_priority = pkg_get_int(maybe, PKG_ARCH_PRIORITY);
+
                                opkg_msg(DEBUG,
                                         "%s arch=%s arch_priority=%d version=%s.\n",
                                         maybe->name, pkg_get_string(maybe, PKG_ARCHITECTURE),
-                                        maybe->arch_priority, pkg_get_string(maybe, PKG_VERSION));
+                                        arch_priority, pkg_get_string(maybe, PKG_VERSION));
                                /* We make sure not to add the same package twice. Need to search for the reason why
                                   they show up twice sometimes. */
-                               if ((maybe->arch_priority > 0)
+                               if ((arch_priority > 0)
                                    &&
                                    (!pkg_vec_contains(matching_pkgs, maybe))) {
                                        max_count++;
@@ -389,9 +393,10 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                int prio = 0;
                for (i = 0; i < matching_pkgs->len; i++) {
                        pkg_t *matching = matching_pkgs->pkgs[i];
-                       if (matching->arch_priority > prio) {
+                       arch_priority = pkg_get_int(matching, PKG_ARCH_PRIORITY);
+                       if (arch_priority > prio) {
                                priorized_matching = matching;
-                               prio = matching->arch_priority;
+                               prio = arch_priority;
                                opkg_msg(DEBUG, "Match %s with priority %i.\n",
                                         matching->name, prio);
                        }
@@ -648,6 +653,8 @@ void hash_insert_pkg(pkg_t * pkg, int set_status)
 
        buildProvides(ab_pkg, pkg);
 
+       init_providelist(pkg, NULL);
+
        /* Need to build the conflicts graph before replaces for correct
         * calculation of replaced_by relation.
         */
index 4b2e902..cfa551e 100644 (file)
@@ -25,6 +25,7 @@
 #include "pkg.h"
 #include "opkg_utils.h"
 #include "pkg_parse.h"
+#include "pkg_depends.h"
 #include "libbb/libbb.h"
 
 #include "parse_util.h"
@@ -46,6 +47,7 @@ static void parse_status(pkg_t * pkg, const char *sstr)
 
 static void parse_conffiles(pkg_t * pkg, const char *cstr)
 {
+       conffile_list_t *cl;
        char file_name[1024], md5sum[85];
 
        if (sscanf(cstr, "%1023s %84s", file_name, md5sum) != 2) {
@@ -54,7 +56,10 @@ static void parse_conffiles(pkg_t * pkg, const char *cstr)
                return;
        }
 
-       conffile_list_append(&pkg->conffiles, file_name, md5sum);
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       if (cl)
+               conffile_list_append(cl, file_name, md5sum);
 }
 
 int parse_version(pkg_t * pkg, const char *vstr)
@@ -77,13 +82,15 @@ int parse_version(pkg_t * pkg, const char *vstr)
                vstr = ++colon;
        }
 
-       rev = strrchr(pkg_set_string(pkg, PKG_VERSION, vstr), '-');
+       rev = strrchr(vstr, '-');
 
        if (rev) {
                *rev++ = '\0';
-               pkg_set_ptr(pkg, PKG_REVISION, rev);
+               pkg_set_string(pkg, PKG_REVISION, rev);
        }
 
+       pkg_set_string(pkg, PKG_VERSION, vstr);
+
        return 0;
 }
 
@@ -102,6 +109,7 @@ static int get_arch_priority(const char *arch)
 int pkg_parse_line(void *ptr, const char *line, uint mask)
 {
        pkg_t *pkg = (pkg_t *) ptr;
+       abstract_pkg_t *ab_pkg = NULL;
 
        /* these flags are a bit hackish... */
        static int reading_conffiles = 0, reading_description = 0;
@@ -117,8 +125,8 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
        switch (*line) {
        case 'A':
                if ((mask & PFM_ARCHITECTURE) && is_field("Architecture", line)) {
-                       pkg->arch_priority = get_arch_priority(
-                               pkg_set_string(pkg, PKG_ARCHITECTURE, line + strlen("Architecture") + 1));
+                       pkg_set_int(pkg, PKG_ARCH_PRIORITY, get_arch_priority(
+                               pkg_set_string(pkg, PKG_ARCHITECTURE, line + strlen("Architecture") + 1)));
 
                } else if ((mask & PFM_AUTO_INSTALLED)
                           && is_field("Auto-Installed", line)) {
@@ -136,8 +144,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                        goto dont_reset_flags;
                } else if ((mask & PFM_CONFLICTS)
                           && is_field("Conflicts", line))
-                       pkg->conflicts_str =
-                           parse_list(line, &pkg->conflicts_count, ',', 0);
+                       parse_deplist(pkg, CONFLICTS, line + strlen("Conflicts") + 1);
                break;
 
        case 'D':
@@ -147,8 +154,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                        reading_description = 1;
                        goto dont_reset_flags;
                } else if ((mask & PFM_DEPENDS) && is_field("Depends", line))
-                       pkg->depends_str =
-                           parse_list(line, &pkg->depends_count, ',', 0);
+                       parse_deplist(pkg, DEPEND, line + strlen("Depends") + 1);
                break;
 
        case 'E':
@@ -193,22 +199,17 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                else if ((mask & PFM_PRIORITY) && is_field("Priority", line))
                        pkg_set_string(pkg, PKG_PRIORITY, line + strlen("Priority") + 1);
                else if ((mask & PFM_PROVIDES) && is_field("Provides", line))
-                       pkg->provides_str =
-                           parse_list(line, &pkg->provides_count, ',', 0);
+                       parse_providelist(pkg, line + strlen("Provides") + 1);
                else if ((mask & PFM_PRE_DEPENDS)
                         && is_field("Pre-Depends", line))
-                       pkg->pre_depends_str =
-                           parse_list(line, &pkg->pre_depends_count, ',', 0);
+                       parse_deplist(pkg, PREDEPEND, line + strlen("Pre-Depends") + 1);
                break;
 
        case 'R':
                if ((mask & PFM_RECOMMENDS) && is_field("Recommends", line))
-                       pkg->recommends_str =
-                           parse_list(line, &pkg->recommends_count, ',', 0);
+                       parse_deplist(pkg, RECOMMEND, line + strlen("Recommends") + 1);
                else if ((mask & PFM_REPLACES) && is_field("Replaces", line))
-                       pkg->replaces_str =
-                           parse_list(line, &pkg->replaces_count, ',', 0);
-
+                       parse_replacelist(pkg, line + strlen("Replaces") + 1);
                break;
 
        case 'S':
@@ -225,8 +226,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                else if ((mask & PFM_STATUS) && is_field("Status", line))
                        parse_status(pkg, line);
                else if ((mask & PFM_SUGGESTS) && is_field("Suggests", line))
-                       pkg->suggests_str =
-                           parse_list(line, &pkg->suggests_count, ',', 0);
+                       parse_deplist(pkg, SUGGEST, line + strlen("Suggests") + 1);
                break;
 
        case 'T':