- add M&M synthesis file parser, add mkd2solv tool
authorMichael Schroeder <mls@suse.de>
Thu, 22 Mar 2012 17:17:35 +0000 (18:17 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 22 Mar 2012 17:17:35 +0000 (18:17 +0100)
CMakeLists.txt
ext/CMakeLists.txt
ext/libsolvext.ver
ext/repo_mdk.c [new file with mode: 0644]
ext/repo_mdk.h [new file with mode: 0644]
tools/CMakeLists.txt
tools/mdk2solv.c [new file with mode: 0644]

index 70ecf72..217361c 100644 (file)
@@ -18,6 +18,7 @@ OPTION (ENABLE_SUSEREPO "Build with suse repository support?" OFF)
 OPTION (ENABLE_COMPS "Build with fedora comps support?" OFF)
 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)
 
 #IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4)
 #ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4)
@@ -85,6 +86,7 @@ IF (NOT ENABLE_RPMDB AND
     NOT ENABLE_RPMMD AND
     NOT ENABLE_SUSEREPO AND
     NOT ENABLE_HELIXREPO AND
+    NOT ENABLE_MDKREPO AND
     NOT ENABLE_DEBIAN)
     SET (ENABLE_RPMDB ON)
     SET (ENABLE_RPMDB_PUBKEY ON)
@@ -132,7 +134,7 @@ TEST_BIG_ENDIAN (WORDS_BIGENDIAN)
 # should create config.h with #cmakedefine instead...
 FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
   ENABLE_RPMDB ENABLE_RPMDB_PUBKEY ENABLE_RPMMD ENABLE_SUSEREPO ENABLE_COMPS
-  ENABLE_HELIXREPO ENABLE_DEBIAN)
+  ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_DEBIAN)
   IF(${VAR})
     ADD_DEFINITIONS (-D${VAR}=1)
     SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
index ab2ba90..9e4a6f0 100644 (file)
@@ -50,6 +50,13 @@ IF (ENABLE_HELIXREPO)
        repo_helix.h)
 ENDIF (ENABLE_HELIXREPO)
 
+IF (ENABLE_MDKREPO)
+    SET (libsolvext_SRCS ${libsolvext_SRCS}
+       repo_mdk.c)
+    SET (libsolvext_HEADERS ${libsolvext_HEADERS}
+       repo_mdk.h)
+ENDIF (ENABLE_MDKREPO)
+
 SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
 SET (CMAKE_SHARED_LINKER_FLAGS "${LINK_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/ext/libsolvext.ver")
 
index cc28d75..de8a0f8 100644 (file)
@@ -10,6 +10,7 @@ SOLV_1.0 {
                repo_add_debs;
                repo_add_deltainfoxml;
                repo_add_helix;
+               repo_add_mdk;
                repo_add_products;
                repo_add_pubkeys;
                repo_add_releasefile_products;
diff --git a/ext/repo_mdk.c b/ext/repo_mdk.c
new file mode 100644 (file)
index 0000000..6e44c98
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * 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 "pool.h"
+#include "repo.h"
+#include "util.h"
+#include "chksum.h"
+#include "repo_mdk.h"
+
+static Offset
+parse_deps(Solvable *s, char *bp, Id marker)
+{
+  Pool *pool = s->repo->pool;
+  Offset deps = 0;
+  char *nbp, *ebp;
+  for (; bp; bp = nbp)
+    {
+      int ispre = 0;
+      Id id, evr = 0;
+      int flags = 0;
+
+      nbp = strchr(bp, '@');
+      if (!nbp)
+       ebp = bp + strlen(bp);
+      else
+       {
+         ebp = nbp;
+         *nbp++ = 0;
+       }
+      if (ebp[-1] == ']')
+       {
+         char *sbp = ebp - 1;
+         while (sbp >= bp && *sbp != '[')
+           sbp--;
+         if (sbp >= bp && sbp[1] != '*')
+           {
+             char *fbp;
+             for (fbp = sbp + 1;; fbp++)
+               {
+                 if (*fbp == '>')
+                   flags |= REL_GT;
+                 else if (*fbp == '=')
+                   flags |= REL_EQ;
+                 else if (*fbp == '<')
+                   flags |= REL_LT;
+                 else
+                   break;
+               }
+             if (*fbp == ' ')
+               fbp++;
+             evr = pool_strn2id(pool, fbp, ebp - 1 - fbp, 1);
+             ebp = sbp;
+           }
+       }
+      if (ebp[-1] == ']' && ebp >= bp + 3 && !strncmp(ebp - 3, "[*]", 3))
+       {
+         ispre = 1;
+         ebp -= 3;
+       }
+      id = pool_strn2id(pool, bp, ebp - bp, 1);
+      if (evr)
+       id = pool_rel2id(pool, id, evr, flags, 1);
+      deps = repo_addid_dep(s->repo, deps, id, ispre ? marker : 0);
+      bp = nbp;
+    }
+  return deps;
+}
+
+int
+repo_add_mdk(Repo *repo, FILE *fp, int flags)
+{
+  Pool *pool = repo->pool;
+  Repodata *data;
+  Solvable *s;
+  char *buf;
+  int bufa, bufl;
+
+  data = repo_add_repodata(repo, flags);
+  bufa = 4096;
+  buf = solv_malloc(bufa);
+  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;
+      bufl = 0;
+      if (buf[0] != '@')
+       {
+         pool_debug(pool, SOLV_ERROR, "bad line <%s>\n", buf);
+         continue;
+       }
+      if (!s)
+       s = pool_id2solvable(pool, repo_add_solvable(repo));
+      if (!strncmp(buf + 1, "filesize@", 9))
+       {
+         unsigned long filesize = strtoul(buf + 10, 0, 10);
+         repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned int)((filesize + 1023) / 1024));
+       }
+      else if (!strncmp(buf + 1, "summary@", 8))
+       repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, buf + 9);
+      else if (!strncmp(buf + 1, "provides@", 9))
+       s->provides = parse_deps(s, buf + 10, 0);
+      else if (!strncmp(buf + 1, "requires@", 9))
+       s->requires = parse_deps(s, buf + 10, SOLVABLE_PREREQMARKER);
+      else if (!strncmp(buf + 1, "suggests@", 9))
+       s->suggests = parse_deps(s, buf + 10, 0);
+      else if (!strncmp(buf + 1, "obsoletes@", 10))
+       s->obsoletes = parse_deps(s, buf + 11, 0);
+      else if (!strncmp(buf + 1, "conflicts@", 10))
+       s->conflicts = parse_deps(s, buf + 11, 0);
+      else if (!strncmp(buf + 1, "info@", 5))
+       {
+         char *nvra = buf + 6;
+         char *epochstr;
+         char *arch;
+         char *version;
+         char *filename;
+         if ((epochstr = strchr(nvra, '@')) != 0)
+           {
+             char *sizestr;
+             *epochstr++ = 0;
+             if ((sizestr = strchr(epochstr, '@')) != 0)
+               {
+                 char *groupstr;
+                 unsigned long size;
+                 *sizestr++ = 0;
+                 if ((groupstr = strchr(sizestr, '@')) != 0)
+                   {
+                     char *n;
+                     *groupstr++ = 0;
+                     if ((n = strchr(groupstr, '@')) != 0)
+                       *n = 0;
+                     if (*groupstr)
+                       repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, groupstr);
+                   }
+                 size = strtoul(sizestr, 0, 10);
+                 repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, (unsigned int)((size + 1023) / 1024));
+               }
+           }
+          filename = pool_tmpjoin(pool, nvra, ".rpm", 0);
+         arch = strrchr(nvra, '.');
+         if (arch)
+           {
+             *arch++ = 0;
+             s->arch = pool_str2id(pool, arch, 1);
+           }
+         /* argh, do we have a distepoch or not, check self-provides */
+         if (s->provides)
+           {
+             Id id, lastid, *idp = s->repo->idarraydata + s->provides;
+             lastid = 0;
+             for (idp = s->repo->idarraydata + s->provides; (id = *idp) != 0; idp++)
+               {
+                 const char *evr, *name;
+                 int namel;
+                 Reldep *rd;
+                 if (!ISRELDEP(id))
+                   continue;
+                 rd = GETRELDEP(pool, id);
+                 if (rd->flags != REL_EQ)
+                   continue;
+                 name = pool_id2str(pool, rd->name);
+                 namel = strlen(name);
+                 if (strncmp(name, nvra, namel) != 0 || nvra[namel] != '-')
+                   continue;
+                 evr = pool_id2str(pool, rd->evr);
+                 evr = strrchr(evr, '-');
+                 if (evr && strchr(evr, ':') != 0)
+                   lastid = id;
+               }
+             if (lastid)
+               {
+                 /* self provides found, and it contains a distepoch */
+                 /* replace with self-provides distepoch to get rid of the disttag */
+                 char *nvradistepoch = strrchr(nvra, '-');
+                 if (nvradistepoch)
+                   {
+                     Reldep *rd = GETRELDEP(pool, lastid);
+                     const char *evr = pool_id2str(pool, rd->evr);
+                     evr = strrchr(evr, '-');
+                     if (evr && (evr = strchr(evr, ':')) != 0)
+                       {
+                         if (strlen(evr) < strlen(nvradistepoch))
+                           strcpy(nvradistepoch, evr);
+                       }
+                   }
+               }
+           }
+         version = strrchr(nvra, '-');
+         if (version)
+           {
+             char *release = version;
+             *release = 0;
+             version = strrchr(nvra, '-');
+             *release = '-';
+             if (!version)
+               version = release;
+             *version++ = 0;
+           }
+         else
+           version = "";
+         s->name = pool_str2id(pool, nvra, 1);
+         if (epochstr && *epochstr && strcmp(epochstr, "0") != 0)
+           {
+             char *evr = pool_tmpjoin(pool, epochstr, ":", version);
+             s->evr = pool_str2id(pool, evr, 1);
+           }
+         else
+           s->evr = pool_str2id(pool, version, 1);
+         repodata_set_location(data, s - pool->solvables, 0, 0, filename);
+         if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
+           s->provides = repo_addid_dep(s->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+          s = 0;
+       }
+      else
+       {
+         char *tagend = strchr(buf + 1, '@');
+         if (tagend)
+           *tagend = 0;
+         pool_debug(pool, SOLV_ERROR, "unknown tag <%s>\n", buf + 1);
+         continue;
+       }
+    }
+  if (s)
+    {
+      pool_debug(pool, SOLV_ERROR, "unclosed package at EOF\n");
+      repo_free_solvable_block(s->repo, s - pool->solvables, 1, 1);
+    }
+  solv_free(buf);
+  if (!(flags & REPO_NO_INTERNALIZE))
+    repodata_internalize(data);
+  return 0;
+}
diff --git a/ext/repo_mdk.h b/ext/repo_mdk.h
new file mode 100644 (file)
index 0000000..7a04b38
--- /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_mdk(Repo *repo, FILE *fp, int flags);
+
index 79ef605..86f804d 100644 (file)
@@ -62,6 +62,13 @@ TARGET_LINK_LIBRARIES (comps2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIE
 SET (tools_list ${tools_list} comps2solv)
 ENDIF (ENABLE_COMPS)
 
+IF (ENABLE_MDKREPO)
+ADD_EXECUTABLE (mdk2solv mdk2solv.c)
+TARGET_LINK_LIBRARIES (mdk2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES})
+
+SET (tools_list ${tools_list} mdk2solv)
+ENDIF (ENABLE_MDKREPO)
+
 ADD_EXECUTABLE (installcheck installcheck.c)
 TARGET_LINK_LIBRARIES (installcheck libsolvext libsolv ${SYSTEM_LIBRARIES})
 
diff --git a/tools/mdk2solv.c b/tools/mdk2solv.c
new file mode 100644 (file)
index 0000000..769b5ba
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/*
+ * comps2solv.c
+ * 
+ * parse Mandriva/Mageie synthesis file
+ *
+ * reads from stdin
+ * writes to stdout
+ */
+
+#include <sys/types.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pool.h"
+#include "repo.h"
+#include "repo_mdk.h"
+#include "common_write.h"
+
+int
+main(int argc, char **argv)
+{
+  Pool *pool = pool_create();
+  Repo *repo = repo_create(pool, "<stdin>");
+  repo_add_mdk(repo, stdin, 0);
+  tool_write(repo, 0, 0);
+  pool_free(pool);
+  exit(0);
+}