implement SOLVER_FLAG_BREAK_ORPHANS
[platform/upstream/libsolv.git] / ext / testcase.c
index 13f52df..32547c8 100644 (file)
@@ -58,6 +58,7 @@ static struct jobflags2str {
   { SOLVER_ORUPDATE,  "orupdate" },
   { SOLVER_FORCEBEST, "forcebest" },
   { SOLVER_TARGETED,  "targeted" },
+  { SOLVER_NOTBYUSER, "notbyuser" },
   { SOLVER_SETEV,     "setev" },
   { SOLVER_SETEVR,    "setevr" },
   { SOLVER_SETARCH,   "setarch" },
@@ -97,6 +98,12 @@ static struct solverflags2str {
   { SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES,    "keepexplicitobsoletes", 0 },
   { SOLVER_FLAG_BEST_OBEY_POLICY,           "bestobeypolicy", 0 },
   { SOLVER_FLAG_NO_AUTOTARGET,              "noautotarget", 0 },
+  { SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,        "dupallowdowngrade", 1 },
+  { SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE,       "dupallowarchchange", 1 },
+  { SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,     "dupallowvendorchange", 1 },
+  { SOLVER_FLAG_DUP_ALLOW_NAMECHANGE,       "dupallownamechange", 1 },
+  { SOLVER_FLAG_KEEP_ORPHANS,               "keeporphans", 0 },
+  { SOLVER_FLAG_BREAK_ORPHANS,              "breakorphans", 0 },
   { 0, 0, 0 }
 };
 
@@ -125,6 +132,7 @@ static struct disttype2str {
   { DISTTYPE_RPM,  "rpm" },
   { DISTTYPE_DEB,  "deb" },
   { DISTTYPE_ARCH, "arch" },
+  { DISTTYPE_HAIKU, "haiku" },
   { 0, 0 }
 };
 
@@ -286,21 +294,14 @@ pool_isknownarch(Pool *pool, Id id)
   return 1;
 }
 
-Id
-testcase_str2dep(Pool *pool, char *s)
+static Id
+testcase_str2dep_simple(Pool *pool, const char **sp)
 {
-  char *n, *a;
+  const char *s = *sp;
+  const char *n, *a;
   Id id, evr;
   int flags;
 
-  if ((n = strchr(s, '|')) != 0)
-    {
-      id = testcase_str2dep(pool, n + 1);
-      *n = 0;
-      id = pool_rel2id(pool, testcase_str2dep(pool, s), id, REL_OR, 1);
-      *n = '|';
-      return id;
-    }
   while (*s == ' ' || *s == '\t')
     s++;
   n = s;
@@ -310,9 +311,9 @@ testcase_str2dep(Pool *pool, char *s)
        {
          while (*s && *s != ')')
            s++;
+         continue;
        }
-      else
-        s++;
+      s++;
     }
   if ((a = strchr(n, '.')) != 0 && a + 1 < s && s[-1] != ')')
     {
@@ -333,7 +334,10 @@ testcase_str2dep(Pool *pool, char *s)
   else
     id = pool_strn2id(pool, n, s - n, 1);
   if (!*s)
-    return id;
+    {
+      *sp = s;
+      return id;
+    }
   while (*s == ' ' || *s == '\t')
     s++;
   flags = 0;
@@ -354,7 +358,10 @@ testcase_str2dep(Pool *pool, char *s)
        break;
     }
   if (!flags)
-    return id;
+    {
+      *sp = s;
+      return id;
+    }
   while (*s == ' ' || *s == '\t')
     s++;
   n = s;
@@ -371,9 +378,55 @@ testcase_str2dep(Pool *pool, char *s)
        s++;
       evr = pool_rel2id(pool, evr, pool_strn2id(pool, n, s - n, 1), REL_COMPAT, 1);
     }
+  *sp = s;
   return pool_rel2id(pool, id, evr, flags, 1);
 }
 
+static Id
+testcase_str2dep_complex(Pool *pool, const char **sp)
+{
+  const char *s = *sp;
+  Id id;
+#ifdef ENABLE_COMPLEX_DEPS
+  while (*s == ' ' || *s == '\t')
+    s++;
+  if (*s == '(')
+    {
+      s++;
+      id = testcase_str2dep_complex(pool, &s);
+      if (*s == ')')
+       s++;
+      while (*s == ' ' || *s == '\t')
+       s++;
+    }
+  else
+#endif
+    id = testcase_str2dep_simple(pool, &s);
+  if (*s == '|')
+    {
+      s++;
+      id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_OR, 1);
+    }
+  else if (*s == '&')
+    {
+      s++;
+      id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_AND, 1);
+    }
+  else if (*s == 'I' && s[1] == 'F' && (s[2] == ' ' || s[2] == '\t'))
+    {
+      s += 2;
+      id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_COND, 1);
+    }
+  *sp = s;
+  return id;
+}
+
+Id
+testcase_str2dep(Pool *pool, const char *s)
+{
+  return testcase_str2dep_complex(pool, &s);
+}
+
 const char *
 testcase_repoid2str(Pool *pool, Id repoid)
 {
@@ -1550,16 +1603,26 @@ testcase_solverresult(Solver *solv, int resultflags)
 
   if ((resultflags & TESTCASE_RESULT_UNNEEDED) != 0)
     {
-      Queue q;
+      Queue q, qf;
 
       queue_init(&q);
+      queue_init(&qf);
       solver_get_unneeded(solv, &q, 0);
-      for (i = 0; i < q.count; i++)
+      solver_get_unneeded(solv, &qf, 1);
+      for (i = j = 0; i < q.count; i++)
        {
-         s = pool_tmpjoin(pool, "unneeded ", testcase_solvid2str(pool, q.elements[i]), 0);
+         /* we rely on qf containing a subset of q in the same order */
+         if (j < qf.count && q.elements[i] == qf.elements[j])
+           {
+             s = pool_tmpjoin(pool, "unneeded_filtered ", testcase_solvid2str(pool, q.elements[i]), 0);
+             j++;
+           }
+         else
+           s = pool_tmpjoin(pool, "unneeded ", testcase_solvid2str(pool, q.elements[i]), 0);
          strqueue_push(&sq, s);
        }
       queue_free(&q);
+      queue_free(&qf);
     }
 
   strqueue_sort(&sq);
@@ -2130,22 +2193,26 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp,
          for (i = 1; i < npieces; i++)
            testcase_setsolverflags(solv, pieces[i]);
         }
-      else if (!strcmp(pieces[0], "result") && npieces > 2)
+      else if (!strcmp(pieces[0], "result") && npieces > 1)
        {
          char *result = 0;
          int resultflags = str2resultflags(pool, pieces[1]);
-         const char *rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0);
-         if (!strcmp(pieces[2], "<inline>"))
-           result = read_inline_file(fp, &buf, &bufp, &bufl);
-         else
+         const char *rdata;
+         if (npieces > 2)
            {
-              FILE *rfp = fopen(rdata, "r");
-             if (!rfp)
-               pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", rdata);
+             rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0);
+             if (!strcmp(pieces[2], "<inline>"))
+               result = read_inline_file(fp, &buf, &bufp, &bufl);
              else
                {
-                 result = read_file(rfp);
-                 fclose(rfp);
+                 FILE *rfp = fopen(rdata, "r");
+                 if (!rfp)
+                   pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", rdata);
+                 else
+                   {
+                     result = read_file(rfp);
+                     fclose(rfp);
+                   }
                }
            }
          if (resultp)