- really support DIRSTRARRAY type
authorMichael Schroeder <mls@suse.de>
Fri, 15 Feb 2008 18:58:59 +0000 (18:58 +0000)
committerMichael Schroeder <mls@suse.de>
Fri, 15 Feb 2008 18:58:59 +0000 (18:58 +0000)
- make pool_addfileprovides do something useful

src/pool.c
src/poolid.c
src/repo_solv.c
src/repodata.c
src/repodata.h

index b2c4941..77733c1 100644 (file)
@@ -636,7 +636,9 @@ pool_setdebuglevel(Pool *pool, int level)
 /*************************************************************************/
 
 struct searchfiles {
-  const char **files;
+  Id *ids;
+  char **dirs;
+  char **names;
   int nfiles;
   Map seen;
 };
@@ -647,7 +649,7 @@ static void
 pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf)
 {
   Id dep, sid;
-  const char *s;
+  const char *s, *sr;
 
   while ((dep = *ida++) != 0)
     {
@@ -696,24 +698,66 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct sea
       s = id2str(pool, dep);
       if (*s != '/')
        continue;
-      sf->files = sat_extend(sf->files, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
-      sf->files[sf->nfiles++] = strdup(s);
+      sf->ids = sat_extend(sf->ids, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
+      sf->dirs = sat_extend(sf->dirs, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
+      sf->names = sat_extend(sf->names, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
+      sf->ids[sf->nfiles] = dep;
+      sr = strrchr(s, '/');
+      sf->names[sf->nfiles] = strdup(sr + 1);
+      sf->dirs[sf->nfiles] = sat_malloc(sr - s + 1);
+      if (sr != s)
+        strncpy(sf->dirs[sf->nfiles], s, sr - s);
+      sf->dirs[sf->nfiles][sr - s] = 0;
+      sf->nfiles++;
     }
 }
 
-#if 0
+struct addfileprovides_cbdata {
+  int nfiles;
+  Id *ids;
+  char **dirs;
+  char **names;
+
+  Repodata *olddata;
+  Id *dids;
+  Map useddirs;
+};
+
 static int
-addfileprovides_cb(void *data, Solvable *s, Id key, const char *str)
+addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value)
 {
+  struct addfileprovides_cbdata *cbd = cbdata;
   Pool *pool = s->repo->pool;
+  int i;
   Id id;
-  id = str2id(pool, str, 0);
-  if (!id)
-    return 0;  /* can't happen */
-  s->provides = repo_addid_dep(s->repo, s->provides, id, SOLVABLE_FILEMARKER);
+
+  if (data != cbd->olddata)
+    {
+      map_free(&cbd->useddirs);
+      map_init(&cbd->useddirs, data->dirpool.ndirs);
+      for (i = 0; i < cbd->nfiles; i++)
+       {
+         Id did = repodata_str2dir(data, cbd->dirs[i], 0);
+          cbd->dids[i] = did;
+         if (did)
+           MAPSET(&cbd->useddirs, did);
+       }
+      cbd->olddata = data;
+    }
+  if (!MAPTST(&cbd->useddirs, value->id))
+    return 0;
+  for (i = 0; i < cbd->nfiles; i++)
+    {
+      if (cbd->dids[i] != value->id)
+       continue;
+      if (!strcmp(cbd->names[i], value->str))
+       break;
+    }
+  if (i == cbd->nfiles)
+    return 0;
+  s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER);
   return 0;
 }
-#endif
 
 void
 pool_addfileprovides(Pool *pool, Repo *installed)
@@ -721,7 +765,11 @@ pool_addfileprovides(Pool *pool, Repo *installed)
   Solvable *s;
   Repo *repo;
   struct searchfiles sf, isf;
+  struct addfileprovides_cbdata cbd;
   int i;
+  Id id_filelist;
+
+  id_filelist = str2id(pool, "filelist", 1);
 
   memset(&sf, 0, sizeof(sf));
   map_init(&sf.seen, pool->ss.nstrings + pool->nrels);
@@ -754,32 +802,54 @@ pool_addfileprovides(Pool *pool, Repo *installed)
   map_free(&isf.seen);
   POOL_DEBUG(SAT_DEBUG_STATS, "found %d file dependencies\n", sf.nfiles);
   POOL_DEBUG(SAT_DEBUG_STATS, "found %d installed file dependencies\n", isf.nfiles);
+  cbd.dids = 0;
+  map_init(&cbd.useddirs, 1);
   if (sf.nfiles)
     {
 #if 0
       for (i = 0; i < sf.nfiles; i++)
-       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]);
+       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", id2str(pool, sf.ids[i]));
 #endif
-      sf.files = sat_extend(sf.files, sf.nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
-      sf.files[sf.nfiles++] = 0;
-#if 0
-      pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0);
-#endif
-      sat_free(sf.files);
+      cbd.nfiles = sf.nfiles;
+      cbd.ids = sf.ids;
+      cbd.dirs = sf.dirs;
+      cbd.names = sf.names;
+      cbd.olddata = 0;
+      cbd.dids = sat_realloc2(cbd.dids, sf.nfiles, sizeof(Id));
+      pool_search(pool, 0, id_filelist, 0, 0, addfileprovides_cb, &cbd);
+      sat_free(sf.ids);
+      for (i = 0; i < sf.nfiles; i++)
+       {
+         sat_free(sf.dirs[i]);
+         sat_free(sf.names[i]);
+       }
+      sat_free(sf.dirs);
+      sat_free(sf.names);
     }
   if (isf.nfiles && installed)
     {
 #if 0
       for (i = 0; i < isf.nfiles; i++)
-       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", isf.files[i]);
-#endif
-      isf.files = sat_extend(isf.files, isf.nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK);
-      isf.files[isf.nfiles++] = 0;
-#if 0
-      repo_search(installed, 0, SOLVABLE_FILELIST, (const char *)isf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0);
+       POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", id2str(pool, isf.ids[i]));
 #endif
-      sat_free(isf.files);
+      cbd.nfiles = isf.nfiles;
+      cbd.ids = isf.ids;
+      cbd.dirs = isf.dirs;
+      cbd.names = isf.names;
+      cbd.olddata = 0;
+      cbd.dids = sat_realloc2(cbd.dids, isf.nfiles, sizeof(Id));
+      repo_search(installed, 0, id_filelist, 0, 0, addfileprovides_cb, &cbd);
+      sat_free(isf.ids);
+      for (i = 0; i < isf.nfiles; i++)
+       {
+         sat_free(isf.dirs[i]);
+         sat_free(isf.names[i]);
+       }
+      sat_free(isf.dirs);
+      sat_free(isf.names);
     }
+  map_free(&cbd.useddirs);
+  sat_free(cbd.dids);
   pool_freewhatprovides(pool); /* as we have added provides */
 }
 
index 6911367..4cc9a24 100644 (file)
@@ -110,7 +110,7 @@ rel2id(Pool *pool, Id name, Id evr, int flags, int create)
   /* extend whatprovides_rel if needed */
   if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
     {
-      pool->whatprovides_rel = sat_realloc(pool->whatprovides_rel, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
+      pool->whatprovides_rel = sat_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset));
       memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
     }
   return MAKERELDEP(id);
index 6989663..a6faa3b 100644 (file)
@@ -1262,7 +1262,26 @@ fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, key
                    break;
                }
              break;
-       
+           case TYPE_DIRSTRARRAY:
+             for (;;)
+               {
+                 did = read_id(&data, 0);
+                 if (keys[key].storage == KEY_STORAGE_INCORE)
+                   {
+                     incore_add_id(&data, did);
+                     while ((h = read_u8(&data)) != 0)
+                       incore_add_u8(&data, h);
+                     incore_add_u8(&data, 0);
+                   }
+                 else
+                   {
+                     while (read_u8(&data) != 0)
+                       ;
+                   }
+                 if (!(did & 0x40))
+                   break;
+               }
+             break;
            default:
              skip_item(&data, keys[key].type, numid, numrel);
            }
index 59782b1..e1ee942 100644 (file)
@@ -765,6 +765,63 @@ fprintf(stderr, "repodata_add_dirnumnum %d %d %d %d (%d)\n", entry, dir, num, nu
 }
 
 void
+repodata_add_dirstr(Repodata *data, Id entry, Id keyname, Id dir, const char *str)
+{
+  Id *ida, *pp, stroff;
+  Repokey key;
+  int l;
+
+  l = strlen(str) + 1;
+  data->attrdata = sat_realloc(data->attrdata, data->attrdatalen + l);
+  memcpy(data->attrdata + data->attrdatalen, str, l);
+  stroff = data->attrdatalen;
+  data->attrdatalen += l;
+
+#if 0
+fprintf(stderr, "repodata_add_dirstr %d %d %s (%d)\n", entry, dir, str,  data->attriddatalen);
+#endif
+  if (data->attrs && data->attrs[entry])
+    {
+      for (pp = data->attrs[entry]; *pp; pp += 2)
+        if (data->keys[*pp].name == keyname && data->keys[*pp].type == TYPE_DIRSTRARRAY)
+         break;
+      if (*pp)
+       {
+         int oldsize = 0;
+         for (ida = data->attriddata + pp[1]; *ida; ida += 2)
+           oldsize += 2;
+         if (ida + 1 == data->attriddata + data->attriddatalen)
+           {
+             /* this was the last entry, just append it */
+             data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + 2, sizeof(Id));
+             data->attriddatalen--;    /* overwrite terminating 0  */
+           }
+         else
+           {
+             /* too bad. move to back. */
+             data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + oldsize + 3, sizeof(Id));
+             memcpy(data->attriddata + data->attriddatalen, data->attriddata + pp[1], oldsize * sizeof(Id));
+             pp[1] = data->attriddatalen;
+             data->attriddatalen += oldsize;
+           }
+         data->attriddata[data->attriddatalen++] = dir;
+         data->attriddata[data->attriddatalen++] = stroff;
+         data->attriddata[data->attriddatalen++] = 0;
+         return;
+       }
+    }
+  key.name = keyname;
+  key.type = TYPE_DIRSTRARRAY;
+  key.size = 0;
+  key.storage = KEY_STORAGE_INCORE;
+  data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + 3, sizeof(Id));
+  repodata_set(data, entry, &key, data->attriddatalen);
+  data->attriddata[data->attriddatalen++] = dir;
+  data->attriddata[data->attriddatalen++] = stroff;
+  data->attriddata[data->attriddatalen++] = 0;
+}
+
+void
 repodata_merge_attrs (Repodata *data, Id dest, Id src)
 {
   Id *keyp;
@@ -1024,6 +1081,13 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
                      data_addideof(xd, ida[2], ida[3] ? 0 : 1);
                    }
                  break;
+               case TYPE_DIRSTRARRAY:
+                 for (ida = data->attriddata + id; *ida; ida += 2)
+                   {
+                     data_addideof(xd, ida[0], ida[2] ? 0 : 1);
+                     data_addblob(xd, data->attrdata + ida[1], strlen((char *)(data->attrdata + ida[1])) + 1);
+                   }
+                 break;
                default:
                  fprintf(stderr, "don't know how to handle type %d\n", key->type);
                  exit(1);
index c3e73d8..fee6f38 100644 (file)
@@ -127,6 +127,7 @@ void repodata_set_constant(Repodata *data, Id entry, Id keyname, Id constant);
 void repodata_set_void(Repodata *data, Id entry, Id keyname);
 void repodata_set_str(Repodata *data, Id entry, Id keyname, const char *str);
 void repodata_add_dirnumnum(Repodata *data, Id entry, Id keyname, Id dir, Id num, Id num2);
+void repodata_add_dirstr(Repodata *data, Id entry, Id keyname, Id dir, const char *str);
 void repodata_merge_attrs (Repodata *data, Id dest, Id src);
 
 void repodata_internalize(Repodata *data);