introduce Solvable.kind to remove the need for strcmp()/strchr() when
authorKlaus Kaempf <kkaempf@suse.de>
Thu, 7 Feb 2008 08:53:19 +0000 (08:53 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Thu, 7 Feb 2008 08:53:19 +0000 (08:53 +0000)
accessing the name in libzypp and other applications.
Its also in preparation of per-kind solving (not implemented yet).

The name prefix (e.g. "pattern:") is still kept but only needed for
capability matching. kind is implemented as an offset (unsigned int)
matching the length of the name prefix. Applications can simply use
(solvable.name + solvable.kind) to strip the prefix from the name.

To prevent name clashes, "product:" was renamed to "prod:". Being
seldomly used, this seems to be acceptable.

Missing understandable documentation on the format of .solv files, the
kind value is currently NOT stored but computed on read.
tools/repo_susetags.c is already prepared to write the kind, solv
version6 should support storing kind values in .solv files.

src/pool.c
src/pooltypes.h
src/repo_solv.c
src/solvable.h
tools/dumpsolv.c
tools/repo_susetags.c
tools/repo_write.c

index f4524ac..f16b724 100644 (file)
 
 #define SOLVABLE_BLOCK 255
 
+/*
+ * solvable_kind -> string prefix
+ *
+ */
+
+static const char *kindprefix_data[] = {
+  NULL, NULL, NULL, NULL, NULL, 
+  "prod:", 
+  "patch:",
+  "source:",
+  "pattern:",
+  "nosource"
+};
+
+const char *
+kind_prefix( solvable_kind kind )
+{
+  if (kind >= _KIND_MAX)
+    return NULL;
+  return kindprefix_data[kind];
+}
 
-// list of string constants, so we can do pointer/Id instead of string comparison
-// index into array matches ID_xxx constants in pool.h
 
+/*
+ * list of string constants, so we can do pointer/Id instead of string comparison
+ * index into array matches ID_xxx constants in pool.h
+ */
+  
 static const char *initpool_data[] = {
   "<NULL>",                   // ID_NULL
   "",                         // ID_EMPTY
index 9681f9d..f190959 100644 (file)
@@ -20,6 +20,7 @@
 #define SOLV_VERSION_3 3
 #define SOLV_VERSION_4 4
 #define SOLV_VERSION_5 5
+#define SOLV_VERSION_6 6 /* solvable.kind added */
 
 #define SOLV_FLAG_PACKEDSIZES 1
 #define SOLV_FLAG_VERTICAL    2
index 722b650..2c61340 100644 (file)
@@ -566,6 +566,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
       case SOLV_VERSION_3:
       case SOLV_VERSION_4:
       case SOLV_VERSION_5:
+      case SOLV_VERSION_6:
         break;
       default:
         pool_debug(pool, SAT_ERROR, "unsupported SOLV version\n");
@@ -1097,8 +1098,16 @@ fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, key
              did = read_id(&data, numid + numrel);
              if (idmap)
                did = idmap[did];
-             if (id == SOLVABLE_NAME)
+             if (id == SOLVABLE_NAME) {
                s->name = did;
+               if (s->name) {
+                 /* Yeah, thats ugly. Better store kind as u8 in .solv files */
+                 const char *name = id2str(pool, s->name);
+                 const char *colon = strchr(name, ':');
+                 if (colon)
+                   s->kind = colon - name + 1;
+               }
+             }
              else if (id == SOLVABLE_ARCH)
                s->arch = did;
              else if (id == SOLVABLE_EVR)
index 785128d..c11689f 100644 (file)
 
 struct _Repo;
 
+typedef enum {
+  KIND_PACKAGE = 0,
+  KIND_PRODUCT = 5,         /* strlen("prod:") */
+  KIND_PATCH = 6,           /* strlen("patch:") */
+  KIND_SOURCE = 7,          /* strlen("source:") */
+  KIND_PATTERN = 8,         /* strlen("pattern:") */
+  KIND_NOSOURCE = 9,        /* strlen("nosource:") */
+  _KIND_MAX
+} solvable_kind;
+
+extern const char *kind_prefix( solvable_kind kind );
+
 typedef struct _Solvable {
+  unsigned int kind;           /* one of KIND_xxx */
   Id name;
   Id arch;
   Id evr;                      /* epoch:version-release */
index bcdeb35..100f3cb 100644 (file)
@@ -222,7 +222,7 @@ int main(int argc, char **argv)
       printf("\n");
       printf("solvable %d:\n", n);
       if (s->name || s->evr || s->arch)
-        printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+        printf("name: %s(%s) %s %s\n", id2str(pool, s->name) + s->kind, id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
       if (s->vendor)
         printf("vendor: %s\n", id2str(pool, s->vendor));
       printids(repo, "provides", s->provides);
index c1fd077..0164f02 100644 (file)
@@ -21,7 +21,7 @@
 #include "repo_susetags.h"
 
 struct parsedata {
-  char *kind;
+  solvable_kind kind;
   Repo *repo;
   Repodata *data;
   struct parsedata_common common;
@@ -43,21 +43,27 @@ static char *flagtab[] = {
   "<="
 };
 
+
+/*
+ * adddep
+ * create and add dependency
+ */
+
 static unsigned int
-adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker, char *kind)
+adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker, solvable_kind kind)
 {
   int i, flags;
   Id id, evrid;
   char *sp[4];
 
-  i = split(line + 5, sp, 4);
-  if (i != 1 && i != 3)
+  i = split(line + 5, sp, 4); /* name, ?, evr, ? */
+  if (i != 1 && i != 3) /* expect either 'name' or 'name' '-' 'evr' */
     {
       fprintf(stderr, "Bad dependency line: %s\n", line);
       exit(1);
     }
   if (kind)
-    id = str2id(pool, join2(kind, ":", sp[0]), 1);
+    id = str2id(pool, join2(kind_prefix(kind), sp[0], 0), 1);
   else
     id = str2id(pool, sp[0], 1);
   if (i == 3)
@@ -80,6 +86,11 @@ adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id ma
 Attrstore *attr;
 #endif
 
+/*
+ * add_location
+ * 
+ */
+
 static void
 add_location(struct parsedata *pd, char *line, Solvable *s, unsigned entry)
 {
@@ -160,6 +171,12 @@ nontrivial:
 }
 
 #if 0
+
+/*
+ * add_source
+ * 
+ */
+
 static void
 add_source(struct parsedata *pd, char *line, Solvable *s, unsigned entry, int first)
 {
@@ -236,6 +253,12 @@ add_source(struct parsedata *pd, char *line, Solvable *s, unsigned entry, int fi
 }
 #endif
 
+/*
+ * add_dirline
+ * add a line with directory information
+ * 
+ */
+
 static void
 add_dirline (struct parsedata *pd, char *line)
 {
@@ -260,6 +283,13 @@ fprintf(stderr, "%s -> %d\n", sp[0], dirid);
   pd->ndirs++;
 }
 
+
+/*
+ * id3_cmp
+ * compare 
+ * 
+ */
+
 static int
 id3_cmp (const void *v1, const void *v2)
 {
@@ -268,6 +298,12 @@ id3_cmp (const void *v1, const void *v2)
   return i1[0] - i2[0];
 }
 
+
+/*
+ * commit_diskusage
+ * 
+ */
+
 static void
 commit_diskusage (struct parsedata *pd, unsigned entry)
 {
@@ -340,6 +376,11 @@ commit_diskusage (struct parsedata *pd, unsigned entry)
  | ((unsigned char)c << 8) \
  | ((unsigned char)d))
 
+/*
+ * tag_from_string
+ * 
+ */
+
 static inline unsigned
 tag_from_string (char *cs)
 {
@@ -347,6 +388,13 @@ tag_from_string (char *cs)
   return ((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]);
 }
 
+
+/*
+ * repo_add_susetags
+ * Parse susetags file passed in fp, fill solvables into repo
+ * 
+ */
+
 void
 repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
 {
@@ -377,8 +425,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   line = malloc(1024);
   aline = 1024;
 
-  pd.repo = repo;
+  pd.repo = pd.common.repo = repo;
   pd.data = data;
+  pd.common.pool = pool;
 
   linep = line;
   s = 0;
@@ -456,6 +505,11 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
       if (! (line[0] && line[1] && line[2] && line[3] && line[4] == ':'))
         continue;
       tag = tag_from_string (line);
+
+      /* first appearance of solvable data,
+       * create the solvable
+       */
+      
       if (indesc < 2
           && (tag == CTAG('=', 'P', 'k', 'g')
              || tag == CTAG('=', 'P', 'a', 't')))
@@ -466,9 +520,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
            s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
          if (s && pd.ndirs)
            commit_diskusage (&pd, last_found_pack);
-         pd.kind = 0;
+         pd.kind = KIND_PACKAGE;
          if (line[3] == 't')
-           pd.kind = "pattern";
+           pd.kind = KIND_PATTERN;
          s = pool_id2solvable(pool, repo_add_solvable(repo));
          last_found_pack = (s - pool->solvables) - repo->start;
          if (data)
@@ -478,8 +532,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
              fprintf(stderr, "Bad line: %s\n", line);
              exit(1);
            }
+         s->kind = pd.kind;
          if (pd.kind)
-           s->name = str2id(pool, join2(pd.kind, ":", sp[0]), 1);
+           s->name = str2id(pool, join2(kind_prefix(pd.kind), sp[0], 0), 1);
          else
            s->name = str2id(pool, sp[0], 1);
          s->evr = makeevr(pool, join2(sp[1], "-", sp[2]));
@@ -487,6 +542,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
          s->vendor = vendor;
          continue;
        }
+      
+      /* Shared or Dirinfo appearance of solvable
+       */
       if (indesc >= 2
           && (tag == CTAG('=', 'P', 'k', 'g')
              || tag == CTAG('=', 'P', 'a', 't')))
@@ -495,9 +553,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
            commit_diskusage (&pd, last_found_pack);
          Id name, evr, arch;
          int n, nn;
-         pd.kind = 0;
+         pd.kind = KIND_PACKAGE;
          if (line[3] == 't')
-           pd.kind = "pattern";
+           pd.kind = KIND_PATTERN;
           if (split(line + 5, sp, 5) != 4)
            {
              fprintf(stderr, "Bad line: %s\n", line);
@@ -505,7 +563,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
            }
          s = 0;
          if (pd.kind)
-           name = str2id(pool, join2(pd.kind, ":", sp[0]), 0);
+           name = str2id(pool, join2(kind_prefix(pd.kind), sp[0], 0), 0);
          else
            name = str2id(pool, sp[0], 0);
          evr = makeevr(pool, join2(sp[1], "-", sp[2]));
@@ -551,7 +609,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
            continue;
           case CTAG('=', 'P', 'r', 'q'):
            if (pd.kind)
-             s->requires = adddep(pool, &pd, s->requires, line, 0, 0);
+             s->requires = adddep(pool, &pd, s->requires, line, 0, 0); /* Huh? No PreReq for non-packages ? */
            else
              s->requires = adddep(pool, &pd, s->requires, line, SOLVABLE_PREREQMARKER, 0);
            continue;
index 86b95f3..2af7828 100644 (file)
@@ -1213,7 +1213,7 @@ if (cbdata.dirused)
 
   /* write file header */
   write_u32(fp, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V');
-  write_u32(fp, SOLV_VERSION_5);
+  write_u32(fp, SOLV_VERSION_6);
 
   /* write counts */
   write_u32(fp, nstrings);