support -X option in rpmmd2solv, make add_autopattern available in bindings
[platform/upstream/libsolv.git] / tools / susetags2solv.c
index 05c6832..71c65d8 100644 (file)
 #include <string.h>
 #include <dirent.h>
 #include <zlib.h>
+#include <getopt.h>
 
 #include "pool.h"
 #include "repo.h"
+#include "repo_solv.h"
 #include "repo_susetags.h"
 #include "repo_content.h"
+#ifdef SUSE
+#include "repo_autopattern.h"
+#endif
 #include "common_write.h"
+#include "solv_xfopen.h"
 
 static void
 usage(int status)
 {
   fprintf(stderr, "\nUsage:\n"
-          "susetags2solv [-a][-s][-c <content>][-h]\n"
+          "susetags2solv [-b <base>][-c <content>][-d <descrdir>][-h][-n <name>]\n"
          "  reads a 'susetags' repository from <stdin> and writes a .solv file to <stdout>\n"
+         "  -b <base>: save as multiple files starting with <base>\n"
          "  -c <contentfile> : parse given contentfile (for product information)\n"
           "  -d <descrdir> : do not read from stdin, but use data in descrdir\n"
          "  -h : print help & exit\n"
-         "  -k : don't mix kinds (experimental!)\n"
-         "  -b <base>: save fas multiple files starting with <base>\n"
          "  -n <name>: save attributes as <name>.attr\n"
         );
    exit(status);
 }
 
-static ssize_t
-cookie_gzread(void *cookie, char *buf, size_t nbytes)
+/* content file query */
+static void
+doquery(Pool *pool, Repo *repo, const char *arg)
 {
-  return gzread((gzFile *)cookie, buf, nbytes);
-}
+  char qbuf[256];
+  const char *str;
+  Id id;
 
-static int
-cookie_gzclose(void *cookie)
-{
-  return gzclose((gzFile *)cookie);
-}
-
-FILE *
-myfopen(const char *fn)
-{
-  cookie_io_functions_t cio;
-  char *suf;
-  gzFile *gzf;
-
-  if (!fn)
-    return 0;
-  suf = strrchr(fn, '.');
-  if (!suf || strcmp(suf, ".gz") != 0)
-    return fopen(fn, "r");
-  gzf = gzopen(fn, "r");
-  if (!gzf)
-    return 0;
-  memset(&cio, 0, sizeof(cio));
-  cio.read = cookie_gzread;
-  cio.close = cookie_gzclose;
-  return  fopencookie(gzf, "r", cio);
+  snprintf(qbuf, sizeof(qbuf), "susetags:%s", arg);
+  id = pool_str2id(pool, qbuf, 0);
+  if (!id)
+    return;
+  str = repo_lookup_str(repo, SOLVID_META, id);
+  if (str)
+    printf("%s\n", str);
 }
 
 int
@@ -78,20 +67,24 @@ main(int argc, char **argv)
   const char *attrname = 0;
   const char *descrdir = 0;
   const char *basefile = 0;
-  Id vendor = 0;
+  const char *query = 0;
+  const char *mergefile = 0;
+  Id defvendor = 0;
   int flags = 0;
+#ifdef SUSE
+  int add_auto = 0;
+#endif
   int c;
+  Pool *pool;
+  Repo *repo;
 
-  while ((c = getopt(argc, argv, "hkn:c:d:b:")) >= 0)
+  while ((c = getopt(argc, argv, "hn:c:d:b:q:M:X")) >= 0)
     {
       switch (c)
        {
        case 'h':
          usage(0);
          break;
-       case 'k':
-         flags |= SUSETAGS_KINDS_SEPARATELY;   /* do not use! */
-         break;
        case 'n':
          attrname = optarg;
          break;
@@ -104,26 +97,44 @@ main(int argc, char **argv)
        case 'b':
          basefile = optarg;
          break;
+       case 'q':
+         query = optarg;
+         break;
+       case 'M':
+         mergefile = optarg;
+         break;
+       case 'X':
+#ifdef SUSE
+         add_auto = 1;
+#endif
+         break;
        default:
          usage(1);
          break;
        }
     }
-  Pool *pool = pool_create();
-  Repo *repo = repo_create(pool, "<susetags>");
+  pool = pool_create();
+  repo = repo_create(pool, "<susetags>");
+
+  repo_add_repodata(repo, 0);
+
   if (contentfile)
     {
-      FILE *fp = fopen (contentfile, "r");
+      FILE *fp = fopen(contentfile, "r");
       if (!fp)
         {
          perror(contentfile);
          exit(1);
        }
-      repo_add_content(repo, fp);
-      if (!strncmp (id2str(pool, pool->solvables[repo->start].name), "product:", 8))
-        vendor = pool->solvables[repo->start].vendor;
-      fclose (fp);
+      if (repo_add_content(repo, fp, REPO_REUSE_REPODATA))
+       {
+         fprintf(stderr, "susetags2solv: %s: %s\n", contentfile, pool_errstr(pool));
+         exit(1);
+       }
+      defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR);
+      fclose(fp);
     }
+
   if (attrname)
     {
       /* ensure '.attr' suffix */
@@ -138,6 +149,10 @@ main(int argc, char **argv)
       }
     }
 
+  /*
+   * descrdir path given, open files and read from there
+   */
+  
   if (descrdir)
     {
       char *fnp;
@@ -170,39 +185,71 @@ main(int argc, char **argv)
          files[0] = de;
        }
 
-      fnp = sat_malloc(strlen(descrdir) + 128);
+      fnp = solv_malloc(strlen(descrdir) + 128);
       for (i = 0; i < ndirs; i++)
        {
          char *fn = files[i]->d_name;
 
          if (!strcmp(fn, "packages") || !strcmp(fn, "packages.gz"))
            {
+             FILE *fp;
              sprintf(fnp, "%s/%s", descrdir, fn);
-             FILE *fp = myfopen(fnp);
+             fp = solv_xfopen(fnp, 0);
              if (!fp)
                {
                  perror(fn);
                  exit(1);
                }
-             repo_add_susetags(repo, fp, vendor, 0, flags);
+             if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+               {
+                 fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+                 exit(1);
+               }
              fclose(fp);
            }
          else if (!strcmp(fn, "packages.DU") || !strcmp(fn, "packages.DU.gz"))
            {
+             FILE *fp;
+             sprintf(fnp, "%s/%s", descrdir, fn);
+             fp = solv_xfopen(fnp, 0);
+             if (!fp)
+               {
+                 perror(fn);
+                 exit(1);
+               }
+             if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+               {
+                 fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+                 exit(1);
+               }
+             fclose(fp);
+           }
+         else if (!strcmp(fn, "packages.FL") || !strcmp(fn, "packages.FL.gz"))
+           {
+#if 0
              sprintf(fnp, "%s/%s", descrdir, fn);
-             FILE *fp = myfopen(fnp);
+             FILE *fp = solv_xfopen(fnp, 0);
              if (!fp)
                {
                  perror(fn);
                  exit(1);
                }
-             repo_add_susetags(repo, fp, vendor, 0, flags | SUSETAGS_EXTEND);
+             if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+               {
+                 fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+                 exit(1);
+               }
              fclose(fp);
+#else
+             /* ignore for now. reactivate when filters work */
+             continue;
+#endif
            }
          else if (!strncmp(fn, "packages.", 9))
            {
              char lang[6];
              char *p;
+             FILE *fp;
              sprintf(fnp, "%s/%s", descrdir, fn);
              p = strrchr(fnp, '.');
              if (p && !strcmp(p, ".gz"))
@@ -214,13 +261,17 @@ main(int argc, char **argv)
                continue;
              strcpy(lang, p + 1);
              sprintf(fnp, "%s/%s", descrdir, fn);
-             FILE *fp = myfopen(fnp);
+             fp = solv_xfopen(fnp, 0);
              if (!fp)
                {
                  perror(fn);
                  exit(1);
                }
-             repo_add_susetags(repo, fp, vendor, lang, flags | SUSETAGS_EXTEND);
+             if (repo_add_susetags(repo, fp, defvendor, lang, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+               {
+                 fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+                 exit(1);
+               }
              fclose(fp);
            }
        }
@@ -228,11 +279,42 @@ main(int argc, char **argv)
        free(files[i]);
       free(files);
       free(fnp);
+      repo_internalize(repo);
     }
   else
-    repo_add_susetags(repo, stdin, vendor, 0, flags);
+    {
+      /* read data from stdin */
+      if (repo_add_susetags(repo, stdin, defvendor, 0, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+       {
+         fprintf(stderr, "susetags2solv: %s\n", pool_errstr(pool));
+         exit(1);
+       }
+    }
+  repo_internalize(repo);
+  if (mergefile)
+    {
+      FILE *fp = fopen(mergefile, "r");
+      if (!fp)
+       {
+         perror(mergefile);
+         exit(1);
+       }
+      if (repo_add_solv(repo, fp, 0))
+       {
+         fprintf(stderr, "susetags2solv: %s\n", pool_errstr(pool));
+         exit(1);
+       }
+      fclose(fp);
+    }
+#ifdef SUSE
+  if (add_auto)
+    repo_add_autopattern(repo, 0); 
+#endif
 
-  tool_write(repo, basefile, attrname);
+  if (query)
+    doquery(pool, repo, query);
+  else
+    tool_write(repo, basefile, attrname);
   pool_free(pool);
   exit(0);
 }