poldek: poldek/dbdep.h (REMOVED), poldek/dbpkgset.c (REMOVED), pol...

mis mis at pld-linux.org
Sun Jul 8 18:28:40 CEST 2007


Author: mis                          Date: Sun Jul  8 16:28:40 2007 GMT
Module: poldek                        Tag: HEAD
---- Log message:
dbdep.c

---- Files affected:
poldek/poldek:
   dbdep.h (1.4 -> NONE)  (REMOVED), dbpkgset.c (1.13 -> NONE)  (REMOVED), dbpkgset.h (1.4 -> NONE)  (REMOVED)
poldek/poldek/install:
   dbdep.c (NONE -> 1.1)  (NEW), dbdep.h (NONE -> 1.1)  (NEW), dbpkgset.c (NONE -> 1.1)  (NEW), dbpkgset.h (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: poldek/poldek/install/dbdep.c
diff -u /dev/null poldek/poldek/install/dbdep.c:1.1
--- /dev/null	Sun Jul  8 18:28:40 2007
+++ poldek/poldek/install/dbdep.c	Sun Jul  8 18:28:35 2007
@@ -0,0 +1,413 @@
+/*
+  Copyright (C) 2000 - 2007 Pawel A. Gajda (mis at pld-linux.org)
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License, version 2 as
+  published by the Free Software Foundation (see file COPYING for details).
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+  $Id$
+  Module to track dependencies during resolving them; used
+  by install/ subsys only
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/param.h>          /* for PATH_MAX */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#include <trurl/nassert.h>
+#include <trurl/narray.h>
+#include <trurl/nhash.h>
+#include <trurl/nlist.h>
+#include <trurl/n_snprintf.h>
+#include <trurl/nmalloc.h>
+
+
+#define ENABLE_TRACE 0
+#include "i18n.h"
+#include "log.h"
+#include "pkg.h"
+#include "misc.h"
+#include "dbdep.h"
+#include "pkgfl.h"
+
+extern int poldek_conf_MULTILIB;
+
+static void db_dep_free_pkgs(struct db_dep *db_dep) 
+{
+    if (db_dep->pkgs) {
+        n_array_free(db_dep->pkgs);
+        db_dep->pkgs = NULL;
+    }
+}
+
+
+static
+void db_dep_free(struct db_dep *db_dep) 
+{
+    
+    db_dep_free_pkgs(db_dep);
+    db_dep->req = NULL;
+    db_dep->spkg = NULL;
+    free(db_dep);
+}
+
+tn_hash *db_deps_new(void) 
+{
+    tn_hash *h;
+    h = n_hash_new(213, (tn_fn_free)n_list_free);
+    return h;
+}
+
+
+void db_deps_add(tn_hash *db_deph, struct capreq *req, struct pkg *pkg,
+                 struct pkg *spkg, unsigned flags) 
+{
+    char           *key;
+    int            found = 0;
+    tn_list        *l = NULL;
+
+
+    //if (strcmp(capreq_name(req), "libglade2-devel") == 0) {
+    //    printf("db_deps_add %s\n", capreq_snprintf_s(req));
+    //}
+    
+    DBGF("%s requiredby=%s satisfiedby=%s [type=%s]\n", capreq_snprintf_s(req),
+         pkg_id(pkg), spkg ? pkg_id(spkg) : "NONE",
+         (flags & DBDEP_FOREIGN) ? "foreign" :
+         (flags & DBDEP_DBSATISFIED) ? "db" : "UNKNOWN");
+
+    key = capreq_name(req);
+
+    found = 0;
+    if ((l = n_hash_get(db_deph, key))) {
+        struct db_dep     *dep;
+        tn_list_iterator  it;
+        
+        n_list_iterator_start(l, &it);
+        while ((dep = n_list_iterator_get(&it))) {
+            if (dep->req == NULL) {
+                dep->req = req;
+                dep->spkg = spkg;
+                dep->pkgs = n_array_new(4, NULL, (tn_fn_cmp)pkg_cmp_name_evr);
+                n_array_push(dep->pkgs, pkg);
+                dep->flags = flags;
+                
+            } else if (capreq_strcmp_evr(dep->req, req) == 0) {
+                n_array_push(dep->pkgs, pkg);
+                dep->flags |= flags;
+                break;
+            }
+        }
+        if (dep) {
+            n_array_sort(dep->pkgs);
+            n_array_uniq(dep->pkgs);
+            found = 1;
+        }
+    }
+
+    if (!found) {
+        struct db_dep *new_dep;
+        
+        new_dep = n_malloc(sizeof(*new_dep));
+        new_dep->req = req;
+        new_dep->spkg = spkg;
+        new_dep->pkgs = n_array_new(4, NULL, (tn_fn_cmp)pkg_cmp_id);
+        n_array_push(new_dep->pkgs, pkg);
+        new_dep->flags = flags;
+
+        if (l == NULL) {         /* new entry */
+            l = n_list_new(0, (tn_fn_free)db_dep_free, NULL);
+            n_hash_insert(db_deph, key, l);
+        }
+        
+        n_list_push(l, new_dep);
+    }
+    
+#if ENABLE_TRACE    
+    db_deps_dump(db_deph);
+#endif    
+}
+
+void db_deps_dump(const tn_hash *db_deph)
+{
+    tn_array *keys;
+    int i;
+
+    msgn(0, "db_deps DUMP");
+    keys = n_hash_keys(db_deph);
+    n_array_sort(keys);
+    
+    for (i=0; i<n_array_size(keys); i++) {
+        const char *key = n_array_nth(keys, i);
+        tn_list *l;
+
+        msgn_i(0, 2, "cap %s", key);
+        if ((l = n_hash_get(db_deph, key))) {
+            struct db_dep     *dep;
+            tn_list_iterator  it;
+            
+            n_list_iterator_start(l, &it);
+            while ((dep = n_list_iterator_get(&it))) {
+                int j;
+                
+                msgn_i(0, 4, "* %s, satisfiedby=%s",
+                       dep->req ? capreq_snprintf_s(dep->req) : "NULL",
+                       dep->spkg ? pkg_id(dep->spkg) : "NONE");
+                if (dep->pkgs)
+                    for (j=0; j<n_array_size(dep->pkgs); j++)
+                        msgn_i(0, 5, "- %s", pkg_id(n_array_nth(dep->pkgs, j)));
+            }
+        }
+    }
+}
+
+
+static
+void db_deps_remove_cap(tn_hash *db_deph, struct pkg *pkg,
+                        struct capreq *cap, int requiredonly)
+{
+    tn_list           *l;
+    tn_list_iterator  it;
+    struct db_dep     *dep;
+
+        
+    if ((l = n_hash_get(db_deph, capreq_name(cap))) == NULL)
+        return;
+    
+    n_list_iterator_start(l, &it);
+    while ((dep = n_list_iterator_get(&it))) {
+        DBGF("- %s (req=%s, pkg=%s)\n", capreq_snprintf_s(cap),
+             dep->req ? capreq_snprintf_s0(dep->req) : "none", pkg_id(pkg));
+        
+        if (dep->req && cap_match_req(cap, dep->req, 1)) {
+            int i, i_del = -1;
+
+            if (!requiredonly) {
+                DBGF("rmcap %s (%s) %s!\n", capreq_snprintf_s(cap),
+                     capreq_snprintf_s0(dep->req), pkg_id(pkg));
+                dep->req = NULL;
+                db_dep_free_pkgs(dep);
+                continue;
+            }
+            
+            DBGF("rmcap %s (%s) %s?\n", capreq_snprintf_s(cap),
+                 capreq_snprintf_s0(dep->req), pkg_id(pkg));
+#if ENABLE_TRACE            
+            pkgs_array_dump(dep->pkgs, "packages");
+#endif            
+            
+            for (i=0; i < n_array_size(dep->pkgs); i++) {
+                DBGF("  %s cmp %s\n", pkg_id(n_array_nth(dep->pkgs, i)),
+                     pkg_id(pkg));
+
+
+                if (pkg_cmp_id(n_array_nth(dep->pkgs, i), pkg) == 0) {
+                    n_assert(i_del == -1);
+                    i_del = i;
+                    if (poldek_conf_MULTILIB &&
+                        !pkg_is_colored_like(n_array_nth(dep->pkgs, i), pkg))
+                        i_del = -1;
+                }
+            }
+            if (i_del >= 0) {
+                DBGF("  --> YES, rmcap %s (%s) %s!\n", capreq_snprintf_s(cap),
+                     capreq_snprintf_s0(dep->req), pkg_id(pkg));
+                n_array_remove_nth(dep->pkgs, i_del);
+                if (n_array_size(dep->pkgs) == 0) {
+                    DBGF(" cap %s COMPLETELY REMOVED\n", capreq_snprintf_s0(dep->req));
+                    dep->req = NULL;
+                    db_dep_free_pkgs(dep);
+
+                }
+            }
+        }
+    }
+}
+
+
+static void remove_files(tn_hash *db_deph, struct pkg *pkg, int load_full_fl) 
+{
+    tn_tuple         *fl;
+    struct pkgflist  *flist = NULL;
+    int              i, j;
+
+    fl = pkg->fl;
+    if (load_full_fl) {
+        if ((flist = pkg_get_flist(pkg)) == NULL ||
+            n_tuple_size(flist->fl) == 0)
+            return;
+
+        fl = flist->fl;
+    }
+
+    if (fl == NULL || n_tuple_size(fl) == 0)
+        return;
+    
+    for (i=0; i < n_tuple_size(fl); i++) {
+        struct pkgfl_ent    *flent = n_tuple_nth(fl, i);
+        char                tmpbuf[PATH_MAX], *slash = "";
+        
+        for (j=0; j < flent->items; j++) {
+            struct flfile     *f = flent->files[j];
+            tn_list           *l;
+            tn_list_iterator  it;
+            struct db_dep     *dep;
+            char              buf[1024];
+            int               n;
+            
+
+            if (S_ISDIR(f->mode)) {
+                struct pkgfl_ent tmpent;
+                
+                if (*flent->dirname != '/')
+                    slash = "/";
+                snprintf(tmpbuf, sizeof(tmpbuf), "%s/%s", flent->dirname,
+                         f->basename);
+                tmpent.dirname = tmpbuf;
+                //if (n_array_bsearch(fl, &tmpent))
+                //    continue;
+            }
+            
+            n = n_snprintf(buf, sizeof(buf), "%s%s%s%s%s",
+                         *flent->dirname == '/' ? "":"/",
+                         flent->dirname,
+                         *flent->dirname == '/' ? "":"/",
+                         f->basename, slash);
+
+            
+            if ((l = n_hash_get(db_deph, buf)) == NULL)
+                continue;
+            
+            n_list_iterator_start(l, &it);
+            while ((dep = n_list_iterator_get(&it))) {
+                if (dep->req && strcmp(capreq_name(dep->req), buf) == 0) {
+                    DBGF("rmcap %s (%s)\n", buf, capreq_snprintf_s0(dep->req));
+                    dep->req = NULL;
+                    db_dep_free_pkgs(dep);
+                }
+            }
+        }
+    }
+    
+    if (flist)
+        pkgflist_free(flist);
+}
+
+
+void db_deps_remove_pkg(tn_hash *db_deph, struct pkg *pkg)
+{
+    int i;
+
+    DBGF("%s\n", pkg_id(pkg));
+    
+    if (pkg->reqs == NULL)
+        return;
+        
+    for (i=0; i < n_array_size(pkg->reqs); i++)
+        db_deps_remove_cap(db_deph, pkg, n_array_nth(pkg->reqs, i), 1);
+
+}
+
+
+void db_deps_remove_pkg_caps(tn_hash *db_deph, struct pkg *pkg, int load_full_fl)
+{
+    int i;
+
+    DBGF("%s\n", pkg_id(pkg));
+    remove_files(db_deph, pkg, load_full_fl);
+    
+    if (pkg->caps == NULL)
+        return;
+    
+    for (i=0; i < n_array_size(pkg->caps); i++) {
+        struct capreq     *cap = n_array_nth(pkg->caps, i);
+        db_deps_remove_cap(db_deph, pkg, cap, 0);
+    }
+}
+
+
+#define DBDEP_PROVIDES_PROVIDES (1 << 0)
+#define DBDEP_PROVIDES_CONTAINS (1 << 1)
+
+static
+struct db_dep *provides_cap(tn_hash *db_deph, struct capreq *cap,
+                            unsigned depflags, unsigned flags) 
+{
+    struct db_dep     *dep = NULL;
+    tn_list           *l = NULL;
+    
+    DBGF("%p %s\n", cap, capreq_snprintf_s0(cap));
+
+    if ((l = n_hash_get(db_deph, capreq_name(cap)))) {
+        tn_list_iterator  it;
+        
+        n_list_iterator_start(l, &it);
+        while ((dep = n_list_iterator_get(&it))) {
+            int matched = 0;
+
+            if (dep->req == NULL) /* removed */
+                continue;
+
+            if (flags & DBDEP_PROVIDES_PROVIDES) {
+                matched = cap_match_req(dep->req, cap, 1);
+                DBGF("cap_match_req(%s, %s) = %d\n", capreq_snprintf_s(dep->req),
+                     capreq_snprintf_s0(cap), matched);
+                //if (strcmp(capreq_name(cap), "libglade2-devel") == 0) {
+                //    printf("cap_match_req %s %s = %d, %s\n", capreq_snprintf_s(dep->req),
+                //           capreq_snprintf_s0(cap), matched,
+                //           dep->spkg ? pkg_snprintf_s(dep->spkg) : "NULL");
+                //    matched = 0;
+                //}
+                
+                    
+                
+            } else if (flags & DBDEP_PROVIDES_CONTAINS) {
+                matched = cap_xmatch_req(cap, dep->req, POLDEK_MA_PROMOTE_REQEPOCH);
+                DBGF("cap_match_req(%s, %s) = %d\n", capreq_snprintf_s(cap),
+                     capreq_snprintf_s0(dep->req), matched);
+            } else
+                n_assert(0);
+            
+            if (matched) {
+                if (depflags && (dep->flags & depflags) == 0)
+                    continue;
+                break;
+            }
+        }
+    }
+
+    DBGF("%s %d (%d)\n", capreq_snprintf_s(cap), dep ? 1:0, l ? n_list_size(l):0);
+    return dep;
+}
+
+
+
+struct db_dep *db_deps_provides(tn_hash *db_deph, struct capreq *cap,
+                                unsigned flags) 
+{
+    return provides_cap(db_deph, cap, flags, DBDEP_PROVIDES_PROVIDES);
+}
+
+
+struct db_dep *db_deps_contains(tn_hash *db_deph, struct capreq *cap,
+                                unsigned flags) 
+{
+    return provides_cap(db_deph, cap, flags, DBDEP_PROVIDES_CONTAINS);
+}
+

================================================================
Index: poldek/poldek/install/dbdep.h
diff -u /dev/null poldek/poldek/install/dbdep.h:1.1
--- /dev/null	Sun Jul  8 18:28:40 2007
+++ poldek/poldek/install/dbdep.h	Sun Jul  8 18:28:35 2007
@@ -0,0 +1,37 @@
+/* $Id$ */
+
+#ifndef  POLDEK_INSTALL_DBDEP_H
+#define  POLDEK_INSTALL_DBDEP_H
+
+#define DBDEP_FOREIGN          (1 << 3)
+#define DBDEP_DBSATISFIED      (1 << 4)
+
+#include <trurl/narray.h>
+#include <trurl/nhash.h>
+
+#include "pkg.h"
+#include "capreq.h"
+
+struct db_dep {
+    struct capreq *req;        /* requirement */
+    struct pkg    *spkg;       /* package which satisfies req */
+    tn_array      *pkgs;       /* packages which requires req */
+    unsigned      flags;       /* DBDEP_* */
+};
+
+tn_hash *db_deps_new(void);
+
+void db_deps_add(tn_hash *db_deph, struct capreq *req, struct pkg *pkg,
+                 struct pkg *spkg, unsigned flags);
+
+void db_deps_remove_pkg(tn_hash *db_deph, struct pkg *pkg);
+void db_deps_remove_pkg_caps(tn_hash *db_deph, struct pkg *pkg, int load_full_fl);
+
+struct db_dep *db_deps_provides(tn_hash *db_deph, struct capreq *cap,
+                                unsigned flags);
+struct db_dep *db_deps_contains(tn_hash *db_deph, struct capreq *cap,
+                                unsigned flags);
+
+void db_deps_dump(const tn_hash *db_deph);
+
+#endif

================================================================
Index: poldek/poldek/install/dbpkgset.c
diff -u /dev/null poldek/poldek/install/dbpkgset.c:1.1
--- /dev/null	Sun Jul  8 18:28:40 2007
+++ poldek/poldek/install/dbpkgset.c	Sun Jul  8 18:28:35 2007
@@ -0,0 +1,172 @@
+/*
+  Copyright (C) 2000 - 2005 Pawel A. Gajda <mis at k2.net.pl>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License, version 2 as
+  published by the Free Software Foundation (see file COPYING for details).
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+  $Id$
+*/
+
+#define ENABLE_TRACE 0
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>          /* for PATH_MAX */
+
+#include <trurl/nassert.h>
+#include <trurl/nhash.h>
+#include <trurl/narray.h>
+#include <trurl/nmalloc.h>
+#include <trurl/nstr.h>
+
+#include "i18n.h"
+#include "pkg.h"
+#include "capreq.h"
+#include "dbpkgset.h"
+#include "log.h"
+
+#define DBPKGSET_CHANGED (1 << 0)
+
+extern int poldek_conf_MULTILIB;
+
+struct dbpkg_set *dbpkg_set_new(void) 
+{
+    struct dbpkg_set *dbpkg_set; 
+
+    dbpkg_set = n_malloc(sizeof(*dbpkg_set));
+    dbpkg_set->dbpkgs = pkgs_array_new_ex(128, pkg_cmp_recno);
+    dbpkg_set->capcache = n_hash_new(128, NULL);
+    return dbpkg_set;
+}
+
+
+void dbpkg_set_free(struct dbpkg_set *dbpkg_set) 
+{
+    n_array_free(dbpkg_set->dbpkgs);
+    n_hash_free(dbpkg_set->capcache);
+    free(dbpkg_set);
+}
+
+void dbpkg_set_add(struct dbpkg_set *dbpkg_set, struct pkg *dbpkg) 
+{
+    n_array_push(dbpkg_set->dbpkgs, dbpkg);
+}
+
+int dbpkg_set_has_pkg_recno(struct dbpkg_set *dbpkg_set, int recno) 
+{
+    struct pkg tmpkg;
+    tmpkg.recno = recno;
+    return n_array_bsearch(dbpkg_set->dbpkgs, &tmpkg) != NULL;
+}
+
+
+int dbpkg_set_has_pkg(struct dbpkg_set *dbpkg_set, const struct pkg *pkg)
+{
+    int i;
+
+    for (i=0; i<n_array_size(dbpkg_set->dbpkgs); i++) {
+        struct pkg *dbpkg = n_array_nth(dbpkg_set->dbpkgs, i);
+        if (pkg_cmp_name_evr(dbpkg, pkg) == 0) {
+            if (poldek_conf_MULTILIB)
+                return pkg_is_colored_like(dbpkg, pkg);
+            else
+                return 1;
+        }
+    }
+    return 0;
+}
+
+
+const struct pkg *dbpkg_set_provides(struct dbpkg_set *dbpkg_set,
+                                     const struct capreq *cap)
+{
+    char             *dirname, *basename, path[PATH_MAX];
+    char             *capnvr = NULL, *capname = NULL;
+    int              i, is_file = 0;
+    struct pkg       *pkg = NULL;
+    
+
+    if (!capreq_has_ver(cap)) {
+        capname = (char*)capreq_name(cap);
+        
+    } else {
+        capname = capnvr = alloca(256);
+        capreq_snprintf(capnvr, 256, cap);
+    }
+    
+    if ((pkg = n_hash_get(dbpkg_set->capcache, capname))) {
+        DBGF("cache hit %s\n", capreq_snprintf_s(cap));
+        return pkg;
+    }
+    
+    if (capreq_is_file(cap)) {
+        is_file = 1;
+        strncpy(path, capreq_name(cap), sizeof(path));
+        path[PATH_MAX - 1] = '\0';
+        n_basedirnam(path, &dirname, &basename);
+        n_assert(dirname);
+        
+        if (*dirname == '\0') { /* path = "/foo" */
+            char *tmp;
+            n_strdupap("/", &tmp);
+            dirname = tmp;
+        }
+        
+        n_assert(*dirname);
+        if (*dirname == '/' && *(dirname + 1) != '\0')
+            dirname++;
+    }
+
+    pkg = NULL;
+    for (i=0; i < n_array_size(dbpkg_set->dbpkgs); i++) {
+        struct pkg *dbpkg = n_array_nth(dbpkg_set->dbpkgs, i);
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list