Imported Upstream version 0.6.28
[platform/upstream/libsolv.git] / tools / testsolv.c
index 6793085..d751246 100644 (file)
@@ -18,28 +18,64 @@ static struct resultflags2str {
   { TESTCASE_RESULT_ORPHANED,           "orphaned" },
   { TESTCASE_RESULT_RECOMMENDED,        "recommended" },
   { TESTCASE_RESULT_UNNEEDED,           "unneeded" },
+  { TESTCASE_RESULT_ALTERNATIVES,       "alternatives" },
+  { TESTCASE_RESULT_RULES,              "rules" },
+  { TESTCASE_RESULT_GENID,              "genid" },
   { 0, 0 }
 };
 
 static void
-usage(ex)
+usage(int ex)
 {
   fprintf(ex ? stderr : stdout, "Usage: testsolv <testcase>\n");
   exit(ex);
 }
 
+struct reportsolutiondata {
+  int count;
+  char *result;
+};
+
+static int
+reportsolutioncb(Solver *solv, void *cbdata)
+{
+  struct reportsolutiondata *sd = cbdata;
+  char *res;
+
+  sd->count++;
+  res = testcase_solverresult(solv, TESTCASE_RESULT_TRANSACTION);
+  if (*res)
+    {
+      char prefix[64];
+      char *p2, *p = res;
+      sprintf(prefix, "callback%d:", sd->count);
+      while ((p2 = strchr(p, '\n')) != 0)
+       {
+         char c = p2[1];
+         p2[1] = 0;
+         sd->result = solv_dupappend(sd->result, prefix, p);
+         p2[1] = c;
+         p = p2 + 1;
+       }
+    }
+  solv_free(res);
+  return 0;
+}
+
 int
 main(int argc, char **argv)
 {
   Pool *pool;
   Queue job;
   Queue solq;
-  Solver *solv;
+  Solver *solv, *reusesolv = 0;
   char *result = 0;
   int resultflags = 0;
   int debuglevel = 0;
   int writeresult = 0;
+  char *writetestcase = 0;
   int multijob = 0;
+  int rescallback = 0;
   int c;
   int ex = 0;
   const char *list = 0;
@@ -47,7 +83,7 @@ main(int argc, char **argv)
   const char *p;
 
   queue_init(&solq);
-  while ((c = getopt(argc, argv, "vrhl:s:")) >= 0)
+  while ((c = getopt(argc, argv, "vmrhl:s:T:")) >= 0)
     {
       switch (c)
       {
@@ -57,6 +93,9 @@ main(int argc, char **argv)
         case 'r':
           writeresult++;
           break;
+        case 'm':
+          rescallback = 1;
+          break;
         case 'h':
          usage(0);
           break;
@@ -69,6 +108,9 @@ main(int argc, char **argv)
          else
            queue_push2(&solq, 1, atoi(optarg));
           break;
+        case 'T':
+         writetestcase = optarg;
+          break;
         default:
          usage(1);
           break;
@@ -96,9 +138,14 @@ main(int argc, char **argv)
          if (!solv)
            {
              pool_free(pool);
-             exit(1);
+             exit(resultflags == 77 ? 77 : 1);
+           }
+         if (reusesolv)
+           {
+             solver_free(solv);
+             solv = reusesolv;
+             reusesolv = 0;
            }
-
          if (!multijob && !feof(fp))
            multijob = 1;
 
@@ -106,8 +153,11 @@ main(int argc, char **argv)
            printf("test %d:\n", multijob++);
          if (list)
            {
+             int selflags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT;
+             if (*list == '/')
+               selflags |= SELECTION_FILELIST;
              queue_empty(&job);
-             selection_make(pool, &job, list, SELECTION_NAME|SELECTION_PROVIDES|SELECTION_FILELIST|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT);
+             selection_make(pool, &job, list, selflags);
              if (!job.elements)
                printf("No match\n");
              else
@@ -124,10 +174,25 @@ main(int argc, char **argv)
          else if (result || writeresult)
            {
              char *myresult, *resultdiff;
+             struct reportsolutiondata reportsolutiondata;
+             memset(&reportsolutiondata, 0, sizeof(reportsolutiondata));
+             if (rescallback)
+               {
+                 solv->solution_callback = reportsolutioncb;
+                 solv->solution_callback_data = &reportsolutiondata;
+               }
              solver_solve(solv, &job);
-             if (!resultflags)
-               resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
+             solv->solution_callback = 0;
+             solv->solution_callback_data = 0;
+             if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) == 0)
+               resultflags |= TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
              myresult = testcase_solverresult(solv, resultflags);
+             if (rescallback && reportsolutiondata.result)
+               {
+                 reportsolutiondata.result = solv_dupjoin(reportsolutiondata.result, myresult, 0);
+                 solv_free(myresult);
+                 myresult = reportsolutiondata.result;
+               }
              if (writeresult)
                {
                  if (*myresult)
@@ -175,6 +240,8 @@ main(int argc, char **argv)
          else
            {
              int pcnt = solver_solve(solv, &job);
+             if (writetestcase)
+               testcase_write(solv, writetestcase, resultflags, 0, 0);
              if (pcnt && solq.count)
                {
                  int i, taken = 0;
@@ -230,8 +297,13 @@ main(int argc, char **argv)
                }
            }
          queue_free(&job);
-         solver_free(solv);
+         if ((resultflags & TESTCASE_RESULT_REUSE_SOLVER) != 0 && !feof(fp))
+           reusesolv = solv;
+         else
+           solver_free(solv);
        }
+      if (reusesolv)
+       solver_free(reusesolv);
       pool_free(pool);
       fclose(fp);
     }