Handle most of the susetags tags. Major exception is 'Shr', where I'm
authorMichael Matz <matz@suse.de>
Tue, 11 Dec 2007 03:18:57 +0000 (03:18 +0000)
committerMichael Matz <matz@suse.de>
Tue, 11 Dec 2007 03:18:57 +0000 (03:18 +0000)
still undecided if I want to copy the info verbatim (easier to use), or
if I want to store the reference expecting the users to follow the chain
on his own.  packages.DU and filelists not yet handled.

src/attr_store.c
src/attr_store.h
src/attr_store_p.h
src/repo_solv.c
tools/dumpattr.c
tools/dumpsolv.c
tools/repo_susetags.c

index c84af85..3d9e2d5 100644 (file)
@@ -32,9 +32,6 @@
 
 /*#define DEBUG_PAGING*/
 
-#define NAME_WIDTH 12
-#define TYPE_WIDTH (16-NAME_WIDTH)
-
 #define BLOB_BLOCK 65535
 
 #define STRINGSPACE_BLOCK 1023
@@ -254,6 +251,14 @@ add_attr_localids_id (Attrstore *s, unsigned int entry, Id name, LocalId id)
     }
 }
 
+void
+add_attr_void (Attrstore *s, unsigned int entry, Id name)
+{
+  LongNV nv;
+  nv.key = add_key (s, name, TYPE_VOID, 0);
+  add_attr (s, entry, nv);
+}
+
 #define pool_debug(a,b,...) fprintf (stderr, __VA_ARGS__)
 
 static Id read_id (FILE *fp, Id max);
@@ -267,6 +272,9 @@ add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, Id *idmap,
   //fprintf (stderr, "%s: attribute in a repo SOLV?\n", id2str (pool, name));
   switch (type)
     {
+      case TYPE_VOID:
+        add_attr_void (s, entry, name);
+       break;
       case TYPE_ATTR_CHUNK:
        {
          unsigned ofs = read_id (fp, 0);
@@ -632,6 +640,8 @@ attr_store_pack (Attrstore *s)
       for (ofs = 0; ofs < num_attrs; ofs++)
        switch (s->keys[nv[ofs].key].type)
          {
+           case TYPE_VOID:
+             break;
            case TYPE_ATTR_INT:
              {
                unsigned int i = nv[ofs].v.i[0];
@@ -734,6 +744,9 @@ attr_store_unpack (Attrstore *s)
         {
          switch (ai.type)
            {
+           case TYPE_VOID:
+             add_attr_void (s, i, ai.name);
+             break;
            case TYPE_ATTR_INT:
              add_attr_int (s, i, ai.name, ai.as_int); 
              break;
index 0b7df7e..61ab5b1 100644 (file)
@@ -37,6 +37,7 @@ void add_attr_blob (Attrstore *s, unsigned int entry, Id name, const void *ptr,
 void add_attr_string (Attrstore *s, unsigned int entry, Id name, const char *val);
 void add_attr_intlist_int (Attrstore *s, unsigned int entry, Id name, int val);
 void add_attr_localids_id (Attrstore *s, unsigned int entry, Id name, LocalId id);
+void add_attr_void (Attrstore *s, unsigned int entry, Id name);
 
 const void * attr_retrieve_blob (Attrstore *s, unsigned int ofs, unsigned int len);
 
index acf7786..4760af0 100644 (file)
@@ -135,6 +135,9 @@ ai_step (Attrstore *s, attr_iterator *ai)
   ai->attrs_next = ai->attrs;
   switch (ai->type)
     {
+    case TYPE_VOID:
+      /* No data.  */
+      break;
     case TYPE_ATTR_INT:
       {
        int val;
index 9f139d4..a01f719 100644 (file)
@@ -837,6 +837,7 @@ repo_add_solv(Repo *repo, FILE *fp)
                  else if (id == SOLVABLE_FRESHENS)
                    s->freshens = ido;
                  break;
+               case TYPE_VOID:
                case TYPE_ATTR_INT:
                case TYPE_ATTR_CHUNK:
                case TYPE_ATTR_STRING:
@@ -933,6 +934,7 @@ repo_add_solv(Repo *repo, FILE *fp)
                POOL_DEBUG(SAT_DEBUG_STATS,"  %s\n", dep2str(pool, repo->idarraydata[ido]));
 #endif
              break;
+           case TYPE_VOID:
            case TYPE_ATTR_INT:
            case TYPE_ATTR_CHUNK:
            case TYPE_ATTR_STRING:
index f6578b5..b59400b 100644 (file)
@@ -71,6 +71,7 @@ dump_attrs (Attrstore *s, unsigned int entry)
            break;
          }
        default:
+         fprintf (stdout, "\n");
          break;
        }
     }
index e120c48..f130227 100644 (file)
@@ -68,6 +68,7 @@ dump_attrs_1 (Attrstore *s, unsigned int entry)
            break;
          }
        default:
+         fprintf (stdout, "\n");
          break;
        }
     }
index f76fe60..932d881 100644 (file)
@@ -42,6 +42,9 @@ struct parsedata {
   Repo *repo;
   char *tmp;
   int tmpl;
+  char **sources;
+  int nsources;
+  int last_found_source;
 };
 
 static Id
@@ -135,6 +138,143 @@ adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, int i
 
 Attrstore *attr;
 
+static void
+add_location (char *line, Solvable *s, unsigned entry)
+{
+  Pool *pool = s->repo->pool;
+  char *sp[3];
+  int i;
+
+  i = split(line, sp, 3);
+  if (i != 2 && i != 3)
+    {
+      fprintf(stderr, "Bad location line: %s\n", line);
+      exit(1);
+    }
+  /* If we have a dirname, let's see if it's the same as arch.  In that
+     case don't store it.  */
+  if (i == 3 && !strcmp (sp[2], id2str (pool, s->arch)))
+    sp[2] = 0, i = 2;
+  if (i == 3 && sp[2])
+    {
+      /* medianr filename dir
+         don't optimize this one */
+      add_attr_int (attr, entry, str2id (pool, "medianr", 1), atoi (sp[0]));
+      add_attr_localids_id (attr, entry, str2id (pool, "mediadir", 1), str2localid (attr, sp[2], 1));
+      add_attr_string (attr, entry, str2id (pool, "mediafile", 1), sp[1]);
+      return;
+    }
+  else
+    {
+      /* Let's see if we can optimize this a bit.  If the media file name
+         can be formed by the base rpm information we don't store it, but
+        only a flag that we've seen it.  */
+      unsigned int medianr = atoi (sp[0]);
+      const char *n1 = sp[1];
+      const char *n2 = id2str (pool, s->name);
+      for (n2 = id2str (pool, s->name); *n2; n1++, n2++)
+        if (*n1 != *n2)
+         break;
+      if (*n2 || *n1 != '-')
+        goto nontrivial;
+
+      n1++;
+      for (n2 = id2str (pool, s->evr); *n2; n1++, n2++)
+       if (*n1 != *n2)
+         break;
+      if (*n2 || *n1 != '.')
+        goto nontrivial;
+      n1++;
+      for (n2 = id2str (pool, s->arch); *n2; n1++, n2++)
+       if (*n1 != *n2)
+         break;
+      if (*n2 || strcmp (n1, ".rpm"))
+        goto nontrivial;
+      add_attr_int (attr, entry, str2id (pool, "medianr", 1), medianr);
+      add_attr_void (attr, entry, str2id (pool, "mediafile", 1));
+      return;
+
+nontrivial:
+      add_attr_int (attr, entry, str2id (pool, "medianr", 1), medianr);
+      add_attr_string (attr, entry, str2id (pool, "mediafile", 1), sp[1]);
+      return;
+    }
+}
+
+static void
+add_source (char *line, struct parsedata *pd, Solvable *s, unsigned entry, int first)
+{
+  Repo *repo = s->repo;
+  Pool *pool = repo->pool;
+  char *sp[5];
+
+  if (split(line, sp, 5) != 4)
+    {
+      fprintf(stderr, "Bad source line: %s\n", line);
+      exit(1);
+    }
+
+  Id name = str2id(pool, sp[0], 1);
+  Id evr = makeevr(pool, join(pd, sp[1], "-", sp[2]));
+  Id arch = str2id(pool, sp[3], 1);
+
+  /* Now, if the source of a package only differs in architecture
+     (src or nosrc), code only that fact.  */
+  if (s->name == name && s->evr == evr
+      && (arch == ARCH_SRC || arch == ARCH_NOSRC))
+    add_attr_void (attr, entry,
+                   str2id (pool, arch == ARCH_SRC ? "source" : "nosource", 1));
+  else if (first)
+    {
+      if (entry >= pd->nsources)
+        {
+         if (pd->nsources)
+           {
+             pd->sources = realloc (pd->sources, (entry + 256) * sizeof (*pd->sources));
+             memset (pd->sources + pd->nsources, 0, (entry + 256 - pd->nsources) * sizeof (*pd->sources));
+           }
+         else
+           pd->sources = calloc (entry + 256, sizeof (*pd->sources));
+         pd->nsources = entry + 256;
+       }
+      /* Uarrr.  Unsplit.  */
+      sp[0][strlen (sp[0])] = ' ';
+      sp[1][strlen (sp[1])] = ' ';
+      sp[2][strlen (sp[2])] = ' ';
+      pd->sources[entry] = strdup (sp[0]);
+    }
+  else
+    {
+      unsigned n, nn;
+      Solvable *found = 0;
+      /* Otherwise we may find a solvable with exactly matching name, evr, arch
+         in the repository already.  In that case encode its ID.  */
+      for (n = repo->start, nn = repo->start + pd->last_found_source;
+           n < repo->end; n++, nn++)
+        {
+         if (nn >= repo->end)
+           nn = repo->start;
+         found = pool->solvables + nn;
+         if (found->repo == repo
+             && found->name == name
+             && found->evr == evr
+             && found->arch == arch)
+           {
+             pd->last_found_source = nn - repo->start;
+             break;
+           }
+        }
+      if (n != repo->end)
+        add_attr_intlist_int (attr, entry, str2id (pool, "sourceid", 1), nn - repo->start);
+      else
+        {
+          add_attr_localids_id (attr, entry, str2id (pool, "source", 1), str2localid (attr, sp[0], 1));
+          add_attr_localids_id (attr, entry, str2id (pool, "source", 1), str2localid (attr, join (pd, sp[1], "-", sp[2]), 1));
+          add_attr_localids_id (attr, entry, str2id (pool, "source", 1), str2localid (attr, sp[3], 1));
+       }
+    }
+}
+
 void
 repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
 {
@@ -146,7 +286,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   int cummulate = 0;
   int indesc = 0;
   int last_found_pack = 0;
-  int pack;
   char *sp[5];
   struct parsedata pd;
 
@@ -159,7 +298,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   pd.repo = repo;
 
   linep = line;
-  pack = 0;
   s = 0;
 
   for (;;)
@@ -213,9 +351,11 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
              exit(1);
            }
          intag = tagend - (line + 1);
-         if (!strncmp (line, "+Des:", 5))
-           cummulate = 1;
-         else if (!strncmp (line, "+Aut:", 5))
+         if (!strncmp (line, "+Des:", 5)
+             || !strncmp (line, "+Eul:", 5)
+             || !strncmp (line, "+Ins:", 5)
+             || !strncmp (line, "+Del:", 5)
+             || !strncmp (line, "+Aut:", 5))
            cummulate = 1;
          else
            cummulate = 0;
@@ -272,7 +412,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
            name = str2id(pool, sp[0], 0);
          evr = makeevr(pool, join(&pd, sp[1], "-", sp[2]));
          arch = str2id(pool, sp[3], 0);
-         /* If we found neither the name of the arch at all in this repo
+         /* If we found neither the name or the arch at all in this repo
             there's no chance of finding the exact solvable either.  */
          if (!name || !arch)
            continue;
@@ -289,7 +429,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
              if (s->repo == repo && s->name == name && s->evr == evr && s->arch == arch)
                break;
            }
-         if (n == pack)
+         if (n == repo->end)
            s = 0;
          else
            last_found_pack = nn - repo->start;
@@ -380,6 +520,36 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
          add_attr_localids_id (attr, last_found_pack, str2id (pool, "license", 1), str2localid (attr, line + 6, 1));
          continue;
        }
+      if (!strncmp(line, "=Loc:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         add_location (line + 6, s, last_found_pack);
+         continue;
+       }
+      if (!strncmp(line, "=Src:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         add_source (line + 6, &pd, s, last_found_pack, 1);
+         continue;
+       }
+      if (!strncmp(line, "=Siz:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         if (split (line + 6, sp, 3) == 2)
+           {
+             add_attr_int (attr, last_found_pack, str2id (pool, "downloadsize", 1), (atoi (sp[0]) + 1023) / 1024);
+             add_attr_int (attr, last_found_pack, str2id (pool, "installsize", 1), (atoi (sp[1]) + 1023) / 1024);
+           }
+         continue;
+       }
+      if (!strncmp(line, "=Tim:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         unsigned int t = atoi (line + 6);
+         if (t)
+           add_attr_int (attr, last_found_pack, str2id (pool, "time", 1), t);
+         continue;
+       }
       if (!strncmp(line, "=Kwd:", 5))
         {
          ensure_entry (attr, last_found_pack);
@@ -404,6 +574,31 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
          add_attr_blob (attr, last_found_pack, str2id (pool, "description", 1), line + 6, strlen (line + 6) + 1);
          continue;
        }
+      if (!strncmp(line, "=Eul:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         add_attr_blob (attr, last_found_pack, str2id (pool, "eula", 1), line + 6, strlen (line + 6) + 1);
+         continue;
+       }
+      if (!strncmp(line, "=Ins:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         add_attr_blob (attr, last_found_pack, str2id (pool, "messageins", 1), line + 6, strlen (line + 6) + 1);
+         continue;
+       }
+      if (!strncmp(line, "=Del:", 5))
+        {
+         ensure_entry (attr, last_found_pack);
+         add_attr_blob (attr, last_found_pack, str2id (pool, "messagedel", 1), line + 6, strlen (line + 6) + 1);
+         continue;
+       }
+      if (!strncmp(line, "=Shr:", 5))
+        {
+         /* XXX Not yet handled.  Two possibilities: either include all
+            referenced data verbatim here, or write out the sharing
+            information.  */
+         continue;
+       }
       if (!strncmp(line, "=Ver:", 5))
        {
          last_found_pack = 0;
@@ -416,6 +611,17 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
   if (s)
     s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
     
+  if (pd.sources)
+    {
+      int i;
+      for (i = 0; i < pd.nsources; i++)
+        if (pd.sources[i])
+         {
+           add_source (pd.sources[i], &pd, pool->solvables + repo->start + i, i, 0);
+           free (pd.sources[i]);
+         }
+      free (pd.sources);
+    }
   if (pd.tmp)
     free(pd.tmp);
   free(line);