- support for legacy rewriting
authorMichael Schroeder <mls@suse.de>
Fri, 5 Oct 2007 22:53:16 +0000 (22:53 +0000)
committerMichael Schroeder <mls@suse.de>
Fri, 5 Oct 2007 22:53:16 +0000 (22:53 +0000)
- support for and/or/with deps
- support freshens

15 files changed:
src/pool.c
src/pool.h
src/poolid.c
src/poolid.h
src/solver.c
src/source.c
src/source.h
src/source_solv.c
tools/dumpsolv.c
tools/source_helix.c
tools/source_patchxml.c
tools/source_rpmdb.c
tools/source_rpmmd.c
tools/source_susetags.c
tools/source_write.c

index 6a4a20f..0abf7da 100644 (file)
@@ -307,15 +307,50 @@ addrelproviders(Pool *pool, Id d)
   Id evr = rd->evr;
   int flags = rd->flags;
   Id pid, *pidp;
-  Id p, *pp;
+  Id p, *pp, *pp2, *pp3;
 
   d = GETRELID(pool, d);
   queueinit_buffer(&plist, buf, sizeof(buf)/sizeof(*buf));
+  switch (flags)
+    {
+    case REL_AND:
+    case REL_WITH:
+      pp = GET_PROVIDESP(name, p);
+      pp2 = GET_PROVIDESP(evr, p);
+      while ((p = *pp++) != 0)
+       {
+         for (pp3 = pp2; *pp3;)
+           if (*pp3++ == p)
+             {
+               queuepush(&plist, p);
+               break;
+             }
+       }
+      break;
+    case REL_OR:
+      pp = GET_PROVIDESP(name, p);
+      while ((p = *pp++) != 0)
+       queuepush(&plist, p);
+      pp = GET_PROVIDESP(evr, p);
+      while ((p = *pp++) != 0)
+       queuepushunique(&plist, p);
+      break;
+    case REL_NAMESPACE:
+      /* unknown namespace, just pass through */
+      pp = GET_PROVIDESP(evr, p);
+      while ((p = *pp++) != 0)
+       queuepush(&plist, p);
+      break;
+    default:
+      break;
+    }
+
+  /* convert to whatprovides id */
 #if 0
   if (pool->verbose)
     printf("addrelproviders: what provides %s?\n", id2str(pool, name));
 #endif
-  if (flags)
+  if (flags && flags < 8)
     {
       FOR_PROVIDES(p, pp, name)
        {
index 1a11e66..d039fe9 100644 (file)
@@ -109,9 +109,14 @@ struct _Pool {
 #define GETRELID(pool, id) ((pool)->nstrings + ((id) ^ 0x80000000))     /* returns Id  */
 #define GETRELDEP(pool, id) ((pool)->rels + ((id) ^ 0x80000000))       /* returns Reldep* */
 
-#define REL_GT 1
-#define REL_EQ 2
-#define REL_LT 4
+#define REL_GT         1
+#define REL_EQ         2
+#define REL_LT         4
+
+#define REL_AND                16
+#define REL_OR         17
+#define REL_WITH       18
+#define REL_NAMESPACE  19
 
 extern Pool *pool_create(void);
 extern void pool_free(Pool *pool);
index a598514..53ad7ff 100644 (file)
@@ -170,6 +170,8 @@ id2str(Pool *pool, Id id)
   if (ISRELDEP(id))
     {
       Reldep *rd = GETRELDEP(pool, id);
+      if (ISRELDEP(rd->name))
+       return "REL";
       return pool->stringspace + pool->strings[rd->name];
     }
   return pool->stringspace + pool->strings[id];
@@ -195,7 +197,23 @@ id2rel(Pool *pool, Id id)
   if (!ISRELDEP(id))
     return "";
   rd = GETRELDEP(pool, id);
-  return rels[rd->flags & 7];
+  switch (rd->flags)
+    {
+    case 0: case 1: case 2: case 3:
+    case 4: case 5: case 6: case 7:
+      return rels[rd->flags & 7];
+    case REL_AND:
+      return " AND ";
+    case REL_OR:
+      return " OR ";
+    case REL_WITH:
+      return " WITH ";
+    case REL_NAMESPACE:
+      return " NAMESPACE ";
+    default:
+      break;
+    }
+  return " ??? ";
 }
 
 
@@ -208,9 +226,81 @@ id2evr(Pool *pool, Id id)
   if (!ISRELDEP(id))
     return "";
   rd = GETRELDEP(pool, id);
+  if (ISRELDEP(rd->evr))
+    return "REL";
   return pool->stringspace + pool->strings[rd->evr];
 }
 
+#define DEP2STRBUF 16
+
+const char *
+dep2str(Pool *pool, Id id)
+{
+  Reldep *rd;
+  const char *sr;
+  char *s1, *s2;
+  int n, l, ls1, ls2, lsr;
+
+  static char *dep2strbuf[DEP2STRBUF];
+  static int   dep2strlen[DEP2STRBUF];
+  static int   dep2strn;
+
+  if (!ISRELDEP(id))
+    return pool->stringspace + pool->strings[id];
+  rd = GETRELDEP(pool, id);
+  n = dep2strn;
+
+  sr = id2rel(pool, id);
+  lsr = strlen(sr);
+
+  s2 = (char *)dep2str(pool, rd->evr);
+  dep2strn = n;
+  ls2 = strlen(s2);
+
+  s1 = (char *)dep2str(pool, rd->name);
+  dep2strn = n;
+  ls1 = strlen(s1);
+
+  if (rd->flags == REL_NAMESPACE)
+    {
+      sr = "(";
+      lsr = 1;
+      ls2++;
+    }
+
+  l = ls1 + ls2 + lsr;
+  if (l + 1 > dep2strlen[n])
+    {
+      if (s1 != dep2strbuf[n])
+        dep2strbuf[n] = xrealloc(dep2strbuf[n], l + 32);
+      else
+       {
+          dep2strbuf[n] = xrealloc(dep2strbuf[n], l + 32);
+          s1 = dep2strbuf[n];
+       }
+      dep2strlen[n] = l + 32;
+    }
+  if (s1 != dep2strbuf[n])
+    {
+      strcpy(dep2strbuf[n], s1);
+      s1 = dep2strbuf[n];
+    }
+  strcpy(s1 + ls1, sr);
+  dep2strbuf[n] = s1 + ls1 + lsr;
+  s2 = (char *)dep2str(pool, rd->evr);
+  if (s2 != dep2strbuf[n])
+    strcpy(dep2strbuf[n], s2);
+  dep2strbuf[n] = s1;
+  if (rd->flags == REL_NAMESPACE)
+    {
+      s1[ls1 + ls2 + lsr - 1] = ')';
+      s1[ls1 + ls2 + lsr] = 0;
+    }
+  dep2strn = (n + 1) % DEP2STRBUF;
+  return s1;
+}
+
+
 void
 pool_shrink_strings(Pool *pool)
 {
index 087d113..406e23d 100644 (file)
@@ -21,6 +21,7 @@ typedef struct _Reldep {
 extern Id str2id(Pool *pool, const char *, int);
 extern Id rel2id(Pool *pool, Id, Id, int, int);
 extern const char *id2str(Pool *pool, Id);
+extern const char *dep2str(Pool *pool, Id);
 extern const char *id2rel(Pool *pool, Id);
 extern const char *id2evr(Pool *pool, Id);
 
index 4a875b8..749a1bb 100644 (file)
@@ -55,6 +55,69 @@ replaces_system(Solver *solv, Id id)
 }
 #endif
 
+static inline int
+dep_is_installed(Solver *solv, Id dep)
+{
+  Pool *pool = solv->pool;
+  Id p, *pp;
+
+  if (ISRELDEP(dep))
+    {
+      Reldep *rd = GETRELDEP(pool, dep);
+      if (rd->flags == REL_AND)
+       {
+         if (!dep_is_installed(solv, rd->name))
+           return 0;
+         return dep_is_installed(solv, rd->evr);
+       }
+    }
+  FOR_PROVIDES(p, pp, dep)
+    {
+      if (solv->decisionmap[p] > 0)
+       return 1;
+    }
+  return 0;
+}
+
+/*
+ * prune_to_recommended
+ *
+ */
+static void
+prune_to_recommended(Solver *solv, Queue *plist)
+{
+  Pool *pool = solv->pool;
+  int i, j;
+  Solvable *s;
+  Id sup, *supp;
+
+  for (i = j = 0; i < plist->count; i++)
+    {
+      s = pool->solvables + plist->elements[i];
+      if (!s->supplements && !s->freshens)
+       continue;
+      if ((supp = s->supplements) != 0)
+       {
+         while ((sup = *supp++) != 0)
+           if (dep_is_installed(solv, sup))
+             break;
+         if (!sup)
+           continue;
+       }
+      if ((supp = s->freshens) != 0)
+       {
+         while ((sup = *supp++) != 0)
+           if (dep_is_installed(solv, sup))
+             break;
+         if (!sup)
+           continue;
+       }
+      plist->elements[j++] = s - pool->solvables;
+    }
+  if (j)
+    plist->count = j;
+}
+
 /*
  * prune_best_version_arch
  * 
@@ -638,7 +701,7 @@ addrulesforsolvable(Solver *solv, Solvable *s, Map *m)
                    }
                  if (!dp[i])          /* no provider found */
                    {
-                     if (pool->verbose) printf("ignoring broken requires %s%s%s of system package %s-%s.%s\n", id2str(pool, req), id2rel(pool, req), id2evr(pool, req), id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+                     if (pool->verbose) printf("ignoring broken requires %s of system package %s-%s.%s\n", dep2str(pool, req), id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
                      continue;
                    }
                }
@@ -647,7 +710,7 @@ addrulesforsolvable(Solver *solv, Solvable *s, Map *m)
                {
                  /* nothing provides req! */
   #if 1
-                 if (pool->verbose) printf("package %s-%s.%s is not installable (%s%s%s)\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch), id2str(pool, req), id2rel(pool, req), id2evr(pool, req));
+                 if (pool->verbose) printf("package %s-%s.%s is not installable (%s)\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch), dep2str(pool, req));
   #endif
                  addrule(solv, -n, 0); /* mark requestor as uninstallable */
                  if (solv->rc_output)
@@ -655,7 +718,7 @@ addrulesforsolvable(Solver *solv, Solvable *s, Map *m)
                  continue;
                }
   #if 0
-             printf("addrule %s-%s.%s %s%s%s %d %d\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch), id2str(pool, req), id2rel(pool, req), id2evr(pool, req), -n, dp - pool->whatprovidesdata);
+             printf("addrule %s-%s.%s %s %d %d\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch), dep2str(pool, req), -n, dp - pool->whatprovidesdata);
              for (i = 0; dp[i]; i++)
                printf("  %s-%s.%s\n", id2str(pool, pool->solvables[dp[i]].name), id2str(pool, pool->solvables[dp[i]].evr), id2str(pool, pool->solvables[dp[i]].arch));
   #endif
@@ -665,8 +728,8 @@ addrulesforsolvable(Solver *solv, Solvable *s, Map *m)
              /* descend the dependency tree */
              for (; *dp != ID_NULL; dp++)   /* loop through all providers */
                {
-                 if (!MAPTST(m, *dp))     /* if not already marked */
-                   queuepush(&q, *dp);    /* queue for installation */
+                 if (!MAPTST(m, *dp))
+                   queuepush(&q, *dp);
                }
 
            } /* while, requirements of n */
@@ -743,15 +806,28 @@ addrulesforsupplements(Solver *solv, Map *m)
       if (MAPTST(m, i))
        continue;
       s = pool->solvables + i;
-      if (!(supp = s->supplements))
-       continue;
-      while ((sup = *supp++) != ID_NULL)
+      sup = 0;
+      if ((supp = s->supplements) != 0)
        {
-         FOR_PROVIDES(p, pp, sup)
-           if (MAPTST(m, p))
-             break;
-         if (p)
-           break;
+         while ((sup = *supp++) != ID_NULL)
+           {
+             FOR_PROVIDES(p, pp, sup)
+               if (MAPTST(m, p))
+                 break;
+             if (p)
+               break;
+           }
+       }
+      if (!sup && (supp = s->freshens) != 0)
+       {
+         while ((sup = *supp++) != ID_NULL)
+           {
+             FOR_PROVIDES(p, pp, sup)
+               if (MAPTST(m, p))
+                 break;
+             if (p)
+               break;
+           }
        }
       if (!sup)
        continue;
@@ -1644,10 +1720,7 @@ run_solver(Solver *solv, int disablerules, int doweak)
 
   /* start SAT algorithm */
   level = 1;
-  if (!solv->updatesystem)
-    systemlevel = 2;
-  else
-    systemlevel = 0;
+  systemlevel = level + 1;
   if (pool->verbose) printf("solving...\n");
 
   queueinit(&dq);
@@ -1677,41 +1750,33 @@ run_solver(Solver *solv, int disablerules, int doweak)
       
       if (level < systemlevel && solv->system->nsolvables)
        {
-         if (pool->verbose) printf("installing system packages\n");
-         for (i = solv->system->start, n = 0; ; i++, n++)
+         if (!solv->updatesystem)
            {
-             if (n == solv->system->nsolvables)
-               break;
-             if (i == solv->system->start + solv->system->nsolvables)
-               i = solv->system->start;
-             s = pool->solvables + i;
-#if 0
-             if (solv->decisionmap[i] < 0)
+             /* try to keep as many packages as possible */
+             if (pool->verbose) printf("installing system packages\n");
+             for (i = solv->system->start, n = 0; ; i++, n++)
                {
-                 int j;
-                 printf("system %s-%s.%s conflicts\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
-                 for (j = 0; j < solv->decisionq.count; j++)
-                   if (solv->decisionq.elements[j] == -i)
-                     break;
-                 if (solv->decisionq_why.elements[j])
-                   printrule(solv, solv->rules + solv->decisionq_why.elements[j]);
-               }
-#endif
-             if (solv->decisionmap[i] != 0)
-               continue;
+                 if (n == solv->system->nsolvables)
+                   break;
+                 if (i == solv->system->start + solv->system->nsolvables)
+                   i = solv->system->start;
+                 s = pool->solvables + i;
+                 if (solv->decisionmap[i] != 0)
+                   continue;
 #if 0
-             printf("system installing %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+                 printf("system installing %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
 #endif
-             olevel = level;
-             level = setpropagatelearn(solv, level, i, disablerules);
-             if (level == 0)
-               {
-                 printf("UNSOLVABLE\n");
-                 queuefree(&dq);
-                 return;
+                 olevel = level;
+                 level = setpropagatelearn(solv, level, i, disablerules);
+                 if (level == 0)
+                   {
+                     printf("UNSOLVABLE\n");
+                     queuefree(&dq);
+                     return;
+                   }
+                 if (level <= olevel)
+                   n = 0;
                }
-             if (level <= olevel)
-               n = 0;
            }
          if (solv->weaksystemrules)
            {
@@ -1720,21 +1785,27 @@ run_solver(Solver *solv, int disablerules, int doweak)
                {
                  if (n == solv->system->nsolvables)
                    break;
-                 if (solv->decisionmap[i] > 0 || solv->weaksystemrules[i - solv->system->start] == 0)
+                 if (solv->decisionmap[i] > 0 || (solv->decisionmap[i] < 0 && solv->weaksystemrules[i - solv->system->start] == 0))
                    continue;
                  QUEUEEMPTY(&dq);
-                 dp = pool->whatprovidesdata + solv->weaksystemrules[i - solv->system->start];
-                 while ((p = *dp++) != 0)
+                 if (solv->decisionmap[i] == 0)
+                   queuepush(&dq, i);
+                 if (solv->weaksystemrules[i - solv->system->start])
                    {
-                     if (solv->decisionmap[p] > 0)
-                       break;
-                     if (solv->decisionmap[p] == 0)
-                       queuepush(&dq, p);
+                     dp = pool->whatprovidesdata + solv->weaksystemrules[i - solv->system->start];
+                     while ((p = *dp++) != 0)
+                       {
+                         if (solv->decisionmap[p] > 0)
+                           break;
+                         if (solv->decisionmap[p] == 0)
+                           queuepush(&dq, p);
+                       }
+                     if (p)
+                       continue;       /* rule is already true */
                    }
-                 if (p || !dq.count)
+                 if (!dq.count)
                    continue;
 
-
                  if (dq.count > 1)
                    prune_best_version_arch(pool, &dq);
 #if 0
@@ -1833,7 +1904,9 @@ run_solver(Solver *solv, int disablerules, int doweak)
              printrule(solv, r);
              abort();
            }
-         prune_best_version_arch(pool, &dq);
+         prune_to_recommended(solv, &dq);
+         if (dq.count > 1)
+           prune_best_version_arch(pool, &dq);
          p = dq.elements[dq.count - 1];
          s = pool->solvables + p;
 #if 0
@@ -1853,12 +1926,9 @@ run_solver(Solver *solv, int disablerules, int doweak)
            n = 0;
        } /* for(), decide */
 
-      /*
-       * check for end
-       */
-      
-      if (n != solv->nrules)
+      if (n != solv->nrules)   /* continue if level < systemlevel */
        continue;
+      
       if (doweak && !solv->problems.count)
        {
          int qcount;
@@ -1874,6 +1944,7 @@ run_solver(Solver *solv, int disablerules, int doweak)
                  Id *recp, rec, *pp, p;
                  s = pool->solvables + i;
                  /* installed, check for recommends */
+                 /* XXX need to special case AND ? */
                  if ((recp = s->recommends) != 0)
                    {
                      while ((rec = *recp++) != 0)
@@ -1882,32 +1953,39 @@ run_solver(Solver *solv, int disablerules, int doweak)
                          FOR_PROVIDES(p, pp, rec)
                            {
                              if (solv->decisionmap[p] > 0)
-                               break;
+                               {
+                                 dq.count = qcount;
+                                 break;
+                               }
                              else if (solv->decisionmap[p] == 0)
                                queuepushunique(&dq, p);
                            }
-                         if (p)
-                           dq.count = qcount;  /* already fulfilled */
                        }
                    }
                }
              else
                {
-                 Id *supp, sup, *pp, p;
+                 Id *supp, sup;
                  s = pool->solvables + i;
+                 if (!s->supplements && !s->freshens)
+                   continue;
                  if ((supp = s->supplements) != 0)
                    {
                      while ((sup = *supp++) != 0)
-                       {
-                         FOR_PROVIDES(p, pp, sup)
-                           {
-                             if (solv->decisionmap[p] > 0)
-                               break;
-                           }
-                         if (p)
-                           queuepushunique(&dq, i);
-                       }
+                       if (dep_is_installed(solv, sup))
+                         break;
+                     if (!sup)
+                       continue;
+                   }
+                 if ((supp = s->freshens) != 0)
+                   {
+                     while ((sup = *supp++) != 0)
+                       if (dep_is_installed(solv, sup))
+                         break;
+                     if (!sup)
+                       continue;
                    }
+                 queuepushunique(&dq, i);
                }
            }
          if (dq.count)
@@ -1915,8 +1993,8 @@ run_solver(Solver *solv, int disablerules, int doweak)
              prune_best_version_arch(pool, &dq);
              p = dq.elements[dq.count - 1];
              s = pool->solvables + p;
-#if 0
-             printf("weak installing %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+#if 1
+             printf("installing recommended %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
 #endif
              level = setpropagatelearn(solv, level, p, 0);
              continue;
@@ -2300,15 +2378,15 @@ solve(Solver *solv, Queue *job)
     addupdaterule(solv, pool->solvables + i, &addedmap, 1, 1, 1);
 #endif
 
+  addrulesforsupplements(solv, &addedmap);
+
   /*
-   * first passed done
+   * first pass done
    * 
    * unify existing rules before going over all job rules
    * 
    */
   
-  addrulesforsupplements(solv, &addedmap);
-
   unifyrules(solv);    /* remove duplicate rpm rules */
 
   /*
index e3582c6..de57d2a 100644 (file)
@@ -280,4 +280,151 @@ pool_freesource(Pool *pool, Source *source)
   xfree(source);
 }
 
+unsigned int
+source_fix_legacy(Source *source, unsigned int provides, unsigned int supplements)
+{
+  Pool *pool = source->pool;
+  const char *p, *dep;
+  Id id, idp, idl, idns;
+  char buf[1024];
+  int i;
+
+  if (provides)
+    {
+      for (i = provides; source->idarraydata[i]; i++)
+       {
+         id = source->idarraydata[i];
+         if (ISRELDEP(id))
+           continue;
+         dep = id2str(pool, id);
+         if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf))
+           {
+             dep += 7;
+             idp = 0;
+             if ((p = strchr(dep, ':')) != 0 && p != dep)
+               {
+                 strncpy(buf, dep, p - dep);
+                 buf[p - dep] = 0;
+                 idp = str2id(pool, buf, 1);
+                 dep = p + 1;
+               }
+             id = 0;
+             while ((p = strchr(dep, ';')) != 0)
+               {
+                 if (p == dep)
+                   {
+                     dep = p + 1;
+                     continue;
+                   }
+                 strcpy(buf, "Locale(");
+                 strncpy(buf + 7, dep, p - dep);
+                 buf[p - dep + 7] = ')';
+                 buf[p - dep + 8] = 0;
+                 idl = str2id(pool, buf, 1);
+                 if (id)
+                   id = rel2id(pool, id, idl, REL_OR, 1);
+                 else
+                   id = idl;
+                 dep = p + 1;
+               }
+             if (dep[0] && dep[1])
+               {
+                 strcpy(buf, "Locale(");
+                 strcpy(buf + 7, dep);
+                 idl = str2id(pool, buf, 1);
+                 if (id)
+                   id = rel2id(pool, id, idl, REL_OR, 1);
+                 else
+                   id = idl;
+               }
+             if (idp)
+               id = rel2id(pool, idp, id, REL_AND, 1);
+             if (id)
+               supplements = source_addid_dep(source, supplements, id, 0);
+           }
+         else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
+           {
+             strncpy(buf, dep, p - dep);
+             buf[p - dep] = 0;
+             idp = str2id(pool, buf, 1);
+             idns = str2id(pool, "namespace:installed", 1);
+             id = str2id(pool, p + 1, 1);
+             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
+             id = rel2id(pool, idp, id, REL_AND, 1);
+             supplements = source_addid_dep(source, supplements, id, 0);
+           }
+       }
+    }
+  if (!supplements)
+    return 0;
+  for (i = supplements; source->idarraydata[i]; i++)
+    {
+      id = source->idarraydata[i];
+      if (ISRELDEP(id))
+       continue;
+      dep = id2str(pool, id);
+      if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
+       {
+         p = strchr(dep + 9, ':');
+         idns = str2id(pool, "namespace:modalias", 1);
+         if (p && p != dep + 9 && strchr(p + 1, ':'))
+           {
+             dep += 9;
+             strncpy(buf, dep, p - dep);
+             buf[p - dep] = 0;
+             idp = str2id(pool, buf, 1);
+             strcpy(buf, p + 1);
+             buf[strlen(buf) - 1] = 0;
+             id = str2id(pool, buf, 1);
+             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
+             id = rel2id(pool, idp, id, REL_AND, 1);
+           }
+         else
+           {
+             dep += 9;
+             strcpy(buf, dep);
+             buf[strlen(buf) - 1] = 0;
+             id = str2id(pool, buf, 1);
+             id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
+           }
+         if (id)
+           source->idarraydata[i] = id;
+       }
+      else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
+       {
+         id = 0;
+         dep += 11;
+         while ((p = strchr(dep, ':')) != 0)
+           {
+             if (p == dep)
+               {
+                 dep = p + 1;
+                 continue;
+               }
+             strncpy(buf, dep, p - dep);
+             buf[p - dep] = 0;
+             idp = str2id(pool, buf, 1);
+             if (id)
+               id = rel2id(pool, id, idp, REL_AND, 1);
+             else
+               id = idp;
+             dep = p + 1;
+           }
+         if (dep[0] && dep[1])
+           {
+             strcpy(buf, dep);
+             buf[strlen(buf) - 1] = 0;
+             idp = str2id(pool, buf, 1);
+             if (id)
+               id = rel2id(pool, id, idp, REL_AND, 1);
+             else
+               id = idp;
+           }
+         if (id)
+           source->idarraydata[i] = id;
+       }
+    }
+  return supplements;
+}
+
 // EOF
index a5b1a99..6a511f8 100644 (file)
@@ -24,6 +24,8 @@ typedef struct _Source {
 extern unsigned int source_addid(Source *source, unsigned int olddeps, Id id);
 extern unsigned int source_addid_dep(Source *source, unsigned int olddeps, Id id, int isreq);
 extern unsigned int source_reserve_ids(Source *source, unsigned int olddeps, int num);
+extern unsigned int source_fix_legacy(Source *source, unsigned int provides, unsigned int supplements);
+
 extern Source *pool_addsource_empty(Pool *pool);
 
 extern const char *source_name(const Source *source);
index 06d0d81..7212183 100644 (file)
@@ -358,8 +358,8 @@ pool_addsource_solv(Pool *pool, FILE *fp, const char *sourcename)
       
       for (i = 0; i < numrel; i++)
        {
-         name = read_id(fp, numid);    /* read (source relative) Ids */
-         evr = read_id(fp, numid);
+         name = read_id(fp, i + numid);        /* read (source relative) Ids */
+         evr = read_id(fp, i + numid);
          flags = read_u8(fp);
          name = idmap[name];           /* map to (pool relative) Ids */
          evr = idmap[evr];
@@ -564,7 +564,7 @@ pool_addsource_solv(Pool *pool, FILE *fp, const char *sourcename)
 #if 0
              printf("%s ->\n", id2str(pool, id));
              for (; *ida; ida++)
-               printf("  %s%s%s\n", id2str(pool, *ida), id2rel(pool, *ida), id2evr(pool, *ida));
+               printf("  %s\n", dep2str(pool, *ida));
 #endif
              break;
            }
index e4d66c3..cb7375a 100644 (file)
@@ -14,7 +14,7 @@ printids(Pool *pool, char *kind, Id *ids)
     return;
   printf("%s:\n", kind);
   while((id = *ids++) != 0)
-    printf("  %s%s%s\n", id2str(pool, id), id2rel(pool, id), id2evr(pool, id));
+    printf("  %s\n", dep2str(pool, id));
 }
 
 int main(int argc, char **argv)
index 8c367aa..89fc57f 100644 (file)
@@ -583,9 +583,8 @@ endElement(void *userData, const char *name)
                         pd->release ? pd->evrspace + pd->release : 0);
       /* ensure self-provides */
       if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
-        {
-          pd->deps[pd->pack].provides = source_addid_dep(pd->source, pd->deps[pd->pack].provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
-        }
+        pd->deps[pd->pack].provides = source_addid_dep(pd->source, pd->deps[pd->pack].provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+      pd->deps[pd->pack].supplements = source_fix_legacy(pd->source, pd->deps[pd->pack].provides, pd->deps[pd->pack].supplements);
       pd->pack++;                     /* inc pack count */
       break;
     case STATE_NAME:
index 413b061..0b22299 100644 (file)
@@ -409,6 +409,7 @@ endElement(void *userData, const char *name)
        s->arch = ARCH_NOARCH;
       if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
         pd->deps[pd->pack].provides = source_addid_dep(pd->source, pd->deps[pd->pack].provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+      pd->deps[pd->pack].supplements = source_fix_legacy(pd->source, pd->deps[pd->pack].provides, pd->deps[pd->pack].supplements);
       pd->pack++;
       break;
     case STATE_NAME:
index b946bcb..6ffd339 100644 (file)
@@ -506,6 +506,7 @@ rpm2solv(Pool *pool, Source *source, Solvable *s, struct deps *deps, RpmHead *rp
   deps->supplements = makedeps(pool, source, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, 2);
   deps->enhances  = makedeps(pool, source, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, 1);
   deps->freshens = 0;
+  deps->supplements = source_fix_legacy(source, deps->provides, deps->supplements);
   return 1;
 }
 
index 709d567..c342c02 100644 (file)
@@ -385,6 +385,7 @@ endElement(void *userData, const char *name)
         s->arch = ARCH_NOARCH;
       if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
         pd->deps[pd->pack].provides = source_addid_dep(pd->source, pd->deps[pd->pack].provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+      pd->deps[pd->pack].supplements = source_fix_legacy(pd->source, pd->deps[pd->pack].provides, pd->deps[pd->pack].supplements);
       pd->pack++;
       break;
     case STATE_NAME:
index 7071605..26830e1 100644 (file)
@@ -224,6 +224,8 @@ pool_addsource_susetags(Pool *pool, FILE *fp)
        {
          if (dp && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
            dp->provides = source_addid_dep(source, dp->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+         if (dp)
+           dp->supplements = source_fix_legacy(source, dp->provides, dp->supplements);
          pd.kind = 0;
          if (line[3] == 't')
            pd.kind = "pattern";
@@ -319,6 +321,8 @@ pool_addsource_susetags(Pool *pool, FILE *fp)
     }
   if (dp && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
     dp->provides = source_addid_dep(source, dp->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+  if (dp)
+    dp->supplements = source_fix_legacy(source, dp->provides, dp->supplements);
     
   pool->nsolvables += pack;
   source->nsolvables = pack;
index 2cac212..f1680c0 100644 (file)
@@ -51,7 +51,15 @@ incneedid(Pool *pool, Id *idarray, NeedId *needid)
        {
          Reldep *rd = GETRELDEP(pool, id);
          needid[GETRELID(pool, id)].need++;
-         needid[rd->evr].need++;
+         if (ISRELDEP(rd->evr))
+           {
+             Id ida[2];
+             ida[0] = rd->evr;
+             ida[1] = 0;
+             incneedid(pool, ida, needid);
+           }
+         else
+           needid[rd->evr].need++;
          id = rd->name;
        }
       needid[id].need++;