- add ENABLE_BZIP2_COMPRESSION and ENABLE_CUDFREPO to support some cudf tests
authorMichael Schroeder <mls@suse.de>
Fri, 22 Jun 2012 09:53:38 +0000 (11:53 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 22 Jun 2012 09:53:38 +0000 (11:53 +0200)
CMakeLists.txt
bindings/CMakeLists.txt
examples/CMakeLists.txt
ext/CMakeLists.txt
ext/repo_cudf.c [new file with mode: 0644]
ext/repo_cudf.h [new file with mode: 0644]
ext/solv_xfopen.c
src/solver.h
tools/CMakeLists.txt
tools/cudftest.c [new file with mode: 0644]

index 54b70bb..2d5b86a 100644 (file)
@@ -20,8 +20,10 @@ OPTION (ENABLE_HELIXREPO "Build with helix repository support?" OFF)
 OPTION (ENABLE_DEBIAN "Build with debian database/repository support?" OFF)
 OPTION (ENABLE_MDKREPO "Build with mandriva/mageia repository support?" OFF)
 OPTION (ENABLE_ARCHREPO "Build with archlinux repository support?" OFF)
+OPTION (ENABLE_CUDFREPO "Build with cudf repository support?" OFF)
 
 OPTION (ENABLE_LZMA_COMPRESSION "Build with lzma/xz compression support?" OFF)
+OPTION (ENABLE_BZIP2_COMPRESSION "Build with bzip2 compression support?" OFF)
 
 #IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4)
 #ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4)
@@ -112,6 +114,9 @@ FIND_PACKAGE (ZLIB REQUIRED)
 IF (ENABLE_LZMA_COMPRESSION)
 FIND_PACKAGE (LZMA REQUIRED)
 ENDIF (ENABLE_LZMA_COMPRESSION)
+IF (ENABLE_BZIP2_COMPRESSION)
+FIND_PACKAGE (BZip2 REQUIRED)
+ENDIF (ENABLE_BZIP2_COMPRESSION)
 
 IF (RPM5)
 MESSAGE (STATUS "Enabling RPM 5 support")
@@ -167,7 +172,7 @@ TEST_BIG_ENDIAN (WORDS_BIGENDIAN)
 FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
   ENABLE_RPMDB ENABLE_RPMDB_PUBKEY ENABLE_RPMMD ENABLE_SUSEREPO ENABLE_COMPS
   ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_ARCHREPO ENABLE_DEBIAN
-  ENABLE_LZMA_COMPRESSION)
+  ENABLE_LZMA_COMPRESSION ENABLE_BZIP2_COMPRESSION)
   IF(${VAR})
     ADD_DEFINITIONS (-D${VAR}=1)
     SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
index b6b9a27..256b522 100644 (file)
@@ -3,6 +3,9 @@ SET (SYSTEM_LIBRARIES ${EXPAT_LIBRARY} ${ZLIB_LIBRARY})
 IF (ENABLE_LZMA_COMPRESSION)
 SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${LZMA_LIBRARY})
 ENDIF (ENABLE_LZMA_COMPRESSION)
+IF (ENABLE_BZIP2_COMPRESSION)
+SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${BZIP2_LIBRARIES})
+ENDIF (ENABLE_BZIP2_COMPRESSION)
 IF (NOT DEBIAN)
 SET (SYSTEM_LIBRARIES ${RPMDB_LIBRARY} ${SYSTEM_LIBRARIES})
 ENDIF (NOT DEBIAN)
index 4b857b8..c75f1c1 100644 (file)
@@ -3,6 +3,9 @@ SET (SYSTEM_LIBRARIES ${EXPAT_LIBRARY} ${ZLIB_LIBRARY})
 IF (ENABLE_LZMA_COMPRESSION)
 SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${LZMA_LIBRARY})
 ENDIF (ENABLE_LZMA_COMPRESSION)
+IF (ENABLE_BZIP2_COMPRESSION)
+SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${BZIP2_LIBRARIES})
+ENDIF (ENABLE_BZIP2_COMPRESSION)
 IF (NOT DEBIAN)
 SET (SYSTEM_LIBRARIES ${RPMDB_LIBRARY} ${SYSTEM_LIBRARIES})
 ENDIF (NOT DEBIAN)
index 025f9cd..d956284 100644 (file)
@@ -64,6 +64,13 @@ IF (ENABLE_ARCHREPO)
        repo_arch.h)
 ENDIF (ENABLE_ARCHREPO)
 
+IF (ENABLE_CUDFREPO)
+    SET (libsolvext_SRCS ${libsolvext_SRCS}
+       repo_cudf.c)
+    SET (libsolvext_HEADERS ${libsolvext_HEADERS}
+       repo_cudf.h)
+ENDIF (ENABLE_CUDFREPO)
+
 SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
 SET (CMAKE_SHARED_LINKER_FLAGS "${LINK_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/ext/libsolvext.ver")
 
diff --git a/ext/repo_cudf.c b/ext/repo_cudf.c
new file mode 100644 (file)
index 0000000..be693ff
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2012, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <zlib.h>
+#include <errno.h>
+
+#include "pool.h"
+#include "repo.h"
+#include "util.h"
+#include "chksum.h"
+#include "solver.h"
+#include "repo_cudf.h"
+
+static Id
+parseonedep(Pool *pool, char *p)
+{
+  char *n, *ne, *e, *ee;
+  Id name, evr;
+  int flags;
+
+  while (*p == ' ' || *p == '\t' || *p == '\n')
+    p++;
+  if (!*p)
+    return 0;
+  if (!strcmp(p, "!true"))
+    return 0;
+  if (!strcmp(p, "!false"))
+    return pool_str2id(pool, p, 1);
+  n = p;
+  /* find end of name */
+  while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '|')
+    p++;
+  ne = p;
+  while (*p == ' ' || *p == '\t' || *p == '\n')
+    p++;
+  evr = 0;
+  flags = 0;
+  e = ee = 0;
+  if (*p == '>' || *p == '<' || *p == '=' || *p == '!')
+    {
+      if (*p == '>')
+       flags |= REL_GT;
+      else if (*p == '=')
+       flags |= REL_EQ;
+      else if (*p == '<')
+       flags |= REL_LT;
+      else if (*p == '!')
+       flags |= REL_LT | REL_GT | REL_EQ;
+      p++;
+      if (flags && *p == '=')
+       {
+         if (p[-1] != '=')
+           flags ^= REL_EQ;
+         p++;
+       }
+      while (*p == ' ' || *p == '\t' || *p == '\n')
+       p++;
+      e = p;
+      while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '|')
+       p++;
+      ee = p;
+      while (*p == ' ' || *p == '\t' || *p == '\n')
+       p++;
+    }
+  name = pool_strn2id(pool, n, ne - n, 1);
+  if (e)
+    {
+      evr = pool_strn2id(pool, e, ee - e, 1);
+      name = pool_rel2id(pool, name, evr, flags, 1);
+    }
+  if (*p == '|')
+    {
+      Id id = parseonedep(pool, p + 1);
+      if (id)
+       name = pool_rel2id(pool, name, id, REL_OR, 1);
+    }
+  return name;
+}
+static unsigned int
+makedeps(Repo *repo, char *deps, unsigned int olddeps, Id marker)
+{
+  Pool *pool = repo->pool;
+  char *p;
+  Id id;
+
+  while ((p = strchr(deps, ',')) != 0)
+    {
+      *p = 0;
+      olddeps = makedeps(repo, deps, olddeps, marker);
+      *p = ',';
+      deps = p + 1;
+    }
+  id = parseonedep(pool, deps);
+  if (!id)
+    return olddeps;
+  return repo_addid_dep(repo, olddeps, id, marker);
+}
+
+static Offset
+copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
+{
+  Id *ida, *from;
+  int cc;
+  Offset off;
+
+  if (!fromoff)
+    return 0;
+  from = fromrepo->idarraydata + fromoff;
+  for (ida = from, cc = 0; *ida; ida++, cc++)
+    ;
+  if (cc == 0)
+    return 0;
+  off = repo_reserve_ids(repo, 0, cc);
+  memcpy(repo->idarraydata + off, from, (cc + 1) * sizeof(Id));
+  repo->idarraysize += cc + 1;
+  return off;
+}
+
+static void
+copysolvabledata(Pool *pool, Solvable *s, Repo *repo)
+{
+  Repo *srepo = s->repo;
+  if (srepo == repo)
+    return;
+  s->provides = copydeps(pool, repo, s->provides, srepo);
+  s->requires = copydeps(pool, repo, s->requires, srepo);
+  s->conflicts = copydeps(pool, repo, s->conflicts, srepo);
+  s->obsoletes = copydeps(pool, repo, s->obsoletes, srepo);
+  s->recommends = copydeps(pool, repo, s->recommends, srepo);
+  s->suggests = copydeps(pool, repo, s->suggests, srepo);
+  s->supplements = copydeps(pool, repo, s->supplements, srepo);
+  s->enhances  = copydeps(pool, repo, s->enhances, srepo);
+}
+
+#define KEEP_VERSION 1
+#define KEEP_PACKAGE 2
+#define KEEP_FEATURE 3
+
+static void
+finishpackage(Pool *pool, Solvable *s, int keep, Queue *job)
+{
+  Id *idp, id, sid;
+  if (!s)
+    return;
+  if (!s->arch)
+    s->arch = ARCH_ANY;
+  if (!s->evr)
+    s->evr = ID_EMPTY;
+  sid = pool_rel2id(pool, s->name, s->evr, REL_EQ, 1);
+  s->provides = repo_addid_dep(s->repo, s->provides, sid, 0); 
+  if (!job || !pool->installed || s->repo != pool->installed)
+    return;
+  if (keep == KEEP_VERSION)
+    queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, sid);
+  else if (keep == KEEP_PACKAGE)
+    queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, s->name);
+  else if (keep == KEEP_FEATURE)
+    {
+      for (idp = s->repo->idarraydata + s->provides; (id = *idp) != 0; idp++)
+       {
+         if (id != sid)        /* skip self-provides */
+           queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, id);
+       }
+    }
+}
+
+int
+repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags)
+{
+  Pool *pool = repo->pool;
+  char *buf, *p;
+  int bufa, bufl, c;
+  Solvable *s;
+  int instanza = 0;
+  int inrequest = 0;
+  int isinstalled = 0;
+  int keep = 0;
+  Repo *xrepo;
+
+  xrepo = repo ? repo : installedrepo;
+  if (!xrepo)
+    return -1;
+
+  buf = solv_malloc(4096);
+  bufa = 4096;
+  bufl = 0;
+  s = 0;
+  while (fgets(buf + bufl, bufa - bufl, fp) > 0)
+    {
+      bufl += strlen(buf + bufl);
+      if (bufl && buf[bufl - 1] != '\n')
+       {
+         if (bufa - bufl < 256)
+           {
+             bufa += 4096;
+             buf = solv_realloc(buf, bufa);
+           }
+         continue;
+       }
+      buf[--bufl] = 0;
+      c = getc(fp);
+      if (c == ' ' || c == '\t')
+       {
+         /* continuation line */
+         buf[bufl++] = ' ';
+         continue;
+       }
+      if (c != EOF)
+       ungetc(c, fp);
+      bufl = 0;
+      if (*buf == '#')
+       continue;
+      if (!*buf)
+       {
+         if (s && !repo && !isinstalled)
+           {
+             repo_free_solvable(repo, s - pool->solvables, 1);
+             s = 0;
+           }
+         if (s)
+           finishpackage(pool, s, keep, job);
+         s = 0;
+         keep = 0;
+         instanza = 0;
+         inrequest = 0;
+         continue;
+       }
+      p = strchr(buf, ':');
+      if (!p)
+       continue;       /* hmm */
+      *p++ = 0;
+      while (*p == ' ' || *p == '\t')
+       p++;
+      if (!instanza)
+       {
+         instanza = 1;
+         inrequest = 0;
+         if (!strcmp(buf, "request"))
+           {
+             inrequest = 1;
+             continue;
+           }
+         if (!strcmp(buf, "package"))
+           {
+             s = pool_id2solvable(pool, repo_add_solvable(xrepo));
+             isinstalled = 0;
+             keep = 0;
+           }
+       }
+      if (inrequest)
+       {
+         if (!job)
+           continue;
+         if (!strcmp(buf, "install"))
+           {
+             Id id, *idp;
+             Offset off = makedeps(xrepo, p, 0, 0);
+             for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
+               queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, id);
+           }
+         else if (!strcmp(buf, "remove"))
+           {
+             Id id, *idp;
+             Offset off = makedeps(xrepo, p, 0, 0);
+             for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
+               queue_push2(job, SOLVER_ERASE|SOLVER_SOLVABLE_PROVIDES, id);
+           }
+         else if (!strcmp(buf, "upgrade"))
+           {
+             Id id, *idp;
+             Offset off = makedeps(xrepo, p, 0, 0);
+             for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
+               queue_push2(job, SOLVER_UPDATE|SOLVER_SOLVABLE_PROVIDES, id);
+           }
+         continue;
+       }
+      if (!s)
+       continue;       /* we ignore the preamble for now */
+      switch (buf[0])
+       {
+       case 'c':
+         if (!strcmp(buf, "conflicts"))
+           {
+             s->conflicts = makedeps(s->repo, p, s->conflicts, 0);
+             continue;
+           }
+       case 'd':
+         if (!strcmp(buf, "depends"))
+           {
+             s->requires = makedeps(s->repo, p, s->requires, 0);
+             continue;
+           }
+         break;
+       case 'k':
+         if (!strcmp(buf, "keep"))
+           {
+             if (!job)
+               continue;
+             if (!strcmp(p, "version"))
+               keep = KEEP_VERSION;
+             else if (!strcmp(p, "package"))
+               keep = KEEP_PACKAGE;
+             else if (!strcmp(p, "feature"))
+               keep = KEEP_FEATURE;
+             continue;
+           }
+         break;
+       case 'i':
+         if (!strcmp(buf, "installed"))
+           {
+             if (!strcmp(p, "true"))
+               {
+                 isinstalled = 1;
+                 if (!installedrepo)
+                   {
+                     repo_free_solvable(repo, s - pool->solvables, 1);
+                     s = 0;
+                   }
+                 else if (s->repo != installedrepo)
+                   {
+                     copysolvabledata(pool, s, installedrepo);
+                     s->repo->nsolvables--;
+                     s->repo = installedrepo;
+                     if (s - pool->solvables < s->repo->start)
+                       s->repo->start = s - pool->solvables;
+                     if (s - pool->solvables >= s->repo->end)
+                       s->repo->end = s - pool->solvables + 1;
+                     s->repo->nsolvables++;
+                   }
+               }
+             continue;
+           }
+         break;
+       case 'p':
+         if (!strcmp(buf, "package"))
+           {
+             s->name = pool_str2id(pool, p, 1);
+             continue;
+           }
+         break;
+       case 'r':
+         if (!strcmp(buf, "depends"))
+           {
+             s->recommends = makedeps(s->repo, p, s->recommends, 0);
+             continue;
+           }
+         break;
+       case 'v':
+         if (!strcmp(buf, "version"))
+           {
+             s->evr = pool_str2id(pool, p, 1);
+             continue;
+           }
+         break;
+       }
+    }
+  if (s && !repo && !isinstalled)
+    {
+      repo_free_solvable(repo, s - pool->solvables, 1);
+      s = 0;
+    }
+  if (s)
+    finishpackage(pool, s, keep, job);
+  solv_free(buf);
+  return 0;
+}
+
diff --git a/ext/repo_cudf.h b/ext/repo_cudf.h
new file mode 100644 (file)
index 0000000..fc9a0d6
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2012, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+extern int repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags);
+
index 71858e5..4de122a 100644 (file)
@@ -75,6 +75,42 @@ static inline FILE *mygzfdopen(int fd, const char *mode)
   return cookieopen(gzf, mode, cookie_gzread, cookie_gzwrite, cookie_gzclose);
 }
 
+#ifdef ENABLE_BZIP2_COMPRESSION
+
+#include <bzlib.h>
+
+/* bzip2 compression */
+
+static ssize_t cookie_bzread(void *cookie, char *buf, size_t nbytes)
+{
+  return BZ2_bzread((BZFILE *)cookie, buf, nbytes);
+}
+
+static ssize_t cookie_bzwrite(void *cookie, const char *buf, size_t nbytes)
+{
+  return BZ2_bzwrite((BZFILE *)cookie, (char *)buf, nbytes);
+}
+
+static int cookie_bzclose(void *cookie)
+{
+  BZ2_bzclose((BZFILE *)cookie);
+  return 0;
+}
+
+static inline FILE *mybzfopen(const char *fn, const char *mode)
+{
+  BZFILE *bzf = BZ2_bzopen(fn, mode);
+  return cookieopen(bzf, mode, cookie_bzread, cookie_bzwrite, cookie_bzclose);
+}
+
+static inline FILE *mybzfdopen(int fd, const char *mode)
+{
+  BZFILE *bzf = BZ2_bzdopen(fd, mode);
+  return cookieopen(bzf, mode, cookie_bzread, cookie_bzwrite, cookie_bzclose);
+}
+
+#endif
+
 
 #ifdef ENABLE_LZMA_COMPRESSION
 
@@ -290,6 +326,10 @@ solv_xfopen(const char *fn, const char *mode)
   if (suf && !strcmp(suf, ".lzma"))
     return mylzfopen(fn, mode);
 #endif
+#ifdef ENABLE_BZIP2_COMPRESSION
+  if (suf && !strcmp(suf, ".bz2"))
+    return mybzfopen(fn, mode);
+#endif
   return fopen(fn, mode);
 }
 
@@ -324,6 +364,10 @@ solv_xfopen_fd(const char *fn, int fd, const char *mode)
   if (suf && !strcmp(suf, ".lzma"))
     return mylzfdopen(fd, simplemode);
 #endif
+#ifdef ENABLE_BZIP2_COMPRESSION
+  if (suf && !strcmp(suf, ".bz2"))
+    return mybzfdopen(fd, simplemode);
+#endif
   return fdopen(fd, mode);
 }
 
index ddab97b..9207557 100644 (file)
@@ -316,7 +316,6 @@ void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps);
 int solver_calc_installsizechange(Solver *solv);
 void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res);
 
-void solver_find_involved(Solver *solv, Queue *installedq, Solvable *s, Queue *q);
 
 /* iterate over all literals of a rule */
 /* WARNING: loop body must not relocate whatprovidesdata, e.g. by
index 681ca55..9fca9c6 100644 (file)
@@ -9,6 +9,9 @@ SET (SYSTEM_LIBRARIES ${EXPAT_LIBRARY} ${ZLIB_LIBRARY})
 IF (ENABLE_LZMA_COMPRESSION)
 SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${LZMA_LIBRARY})
 ENDIF (ENABLE_LZMA_COMPRESSION)
+IF (ENABLE_BZIP2_COMPRESSION)
+SET (SYSTEM_LIBRARIES ${SYSTEM_LIBRARIES} ${BZIP2_LIBRARIES})
+ENDIF (ENABLE_BZIP2_COMPRESSION)
 IF (ENABLE_RPMDB)
 SET (SYSTEM_LIBRARIES ${RPMDB_LIBRARY} ${SYSTEM_LIBRARIES})
 ENDIF (ENABLE_RPMDB)
@@ -82,6 +85,11 @@ TARGET_LINK_LIBRARIES (archrepo2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRA
 SET (tools_list ${tools_list} archpkgs2solv archrepo2solv)
 ENDIF (ENABLE_ARCHREPO)
 
+IF (ENABLE_CUDFREPO)
+ADD_EXECUTABLE (cudftest cudftest.c)
+TARGET_LINK_LIBRARIES (cudftest libsolvext libsolv ${SYSTEM_LIBRARIES})
+ENDIF (ENABLE_CUDFREPO)
+
 ADD_EXECUTABLE (installcheck installcheck.c)
 TARGET_LINK_LIBRARIES (installcheck libsolvext libsolv ${SYSTEM_LIBRARIES})
 
diff --git a/tools/cudftest.c b/tools/cudftest.c
new file mode 100644 (file)
index 0000000..05dea10
--- /dev/null
@@ -0,0 +1,153 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "pool.h"
+#include "evr.h"
+#include "solver.h"
+#include "solverdebug.h"
+#include "repo_cudf.h"
+#include "repo_write.h"
+#include "solv_xfopen.h"
+
+static void
+dump_repo(Repo *repo, char *name)
+{
+  FILE *fp;
+  if ((fp = fopen(name, "w")) == 0)
+    {
+      perror(name);
+      exit(1);
+    }
+  repo_write(repo, fp);
+  fclose(fp);
+}
+
+static int
+sortfunc(const void *ap, const void *bp, void *dp)
+{
+  Pool *pool = dp;
+  Solvable *sa, *sb;
+  sa = pool->solvables + *(Id *)ap;
+  sb = pool->solvables + *(Id *)bp;
+  if (sa->name != sb->name)
+    {
+      int r = strcmp(pool_id2str(pool, sa->name), pool_id2str(pool, sb->name));
+      if (r)
+       return r;
+    }
+  if (sa->evr != sb->evr)
+    {
+      int r = pool_evrcmp(pool, sa->evr, sb->evr, EVRCMP_COMPARE);
+      if (r)
+       return r;
+    }
+  return *(Id *)ap - *(Id *)bp;
+}
+
+int
+main(int argc, char **argv)
+{
+  char *cudfin;
+  char *cudfout = 0;
+  Pool *pool;
+  Repo *installed, *repo;
+  FILE *fp, *ofp;
+  Solver *solv;
+  Transaction *trans;
+  Queue job;
+  Queue dq;
+  int i;
+  int debug = 0;
+
+  while (argc > 1 && !strcmp(argv[1], "-d"))
+    {
+      debug++;
+      argc--;
+      argv++;
+    }
+  if (argc < 2)
+    {
+      fprintf(stderr, "Usage: cudftest <cudfin> [cudfout]");
+      exit(1);
+    }
+  cudfin = argv[1];
+  cudfout = argc > 2 ? argv[2] : 0;
+
+  if ((fp = solv_xfopen(cudfin, 0)) == 0)
+    {
+      perror(cudfin);
+      exit(1);
+    }
+  pool = pool_create();
+  if (debug > 1)
+    pool_setdebuglevel(pool, debug - 1);
+  installed = repo_create(pool, "installed");
+  pool_set_installed(pool, installed);
+  repo = repo_create(pool, "repo");
+  queue_init(&job);
+  repo_add_cudf(repo, installed, fp, &job, 0);
+  pool_createwhatprovides(pool);
+
+  /* debug */
+  if (debug)
+    {
+      dump_repo(installed, "cudf_installed.solv");
+      dump_repo(repo, "cudf_repo.solv");
+    }
+
+  solv = solver_create(pool);
+  solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
+  if (solver_solve(solv, &job) != 0)
+    {
+      int problem;
+      int pcnt = solver_problem_count(solv);
+      printf("Found %d problems:\n", pcnt);
+      for (problem = 1; problem <= pcnt; problem++)
+        {
+          printf("Problem %d:\n", problem);
+          solver_printprobleminfo(solv, problem);
+          printf("\n");
+       }
+    }
+  trans = solver_create_transaction(solv);
+  solver_free(solv);
+
+  if (debug)
+    transaction_print(trans);
+
+  queue_init(&dq);
+  transaction_installedresult(trans, &dq);
+  solv_sort(dq.elements, dq.count, sizeof(Id), sortfunc, pool);
+
+  ofp = stdout;
+  if (cudfout && ((ofp = fopen(cudfout, "w")) == 0))
+    {
+      perror(cudfout);
+      exit(1);
+    }
+  for (i = 0; i < dq.count; i++)
+    {
+      Solvable *s = pool_id2solvable(pool, dq.elements[i]);
+      fprintf(ofp, "package: %s\n", pool_id2str(pool, s->name));
+      fprintf(ofp, "version: %s\n", pool_id2str(pool, s->evr));
+      fprintf(ofp, "installed: true\n");
+      if (s->repo == pool->installed)
+        fprintf(ofp, "was-installed: true\n");
+      fprintf(ofp, "\n");
+    }
+  queue_free(&dq);
+  transaction_free(trans);
+  queue_free(&job);
+  pool_free(pool);
+  if (ofp != stdout)
+    {
+      if (fclose(ofp))
+       {
+         perror("fclose");
+         exit(1);
+       }
+    }
+  exit(0);
+}
+