- get missing translations from other solvables
authorMichael Schroeder <mls@suse.de>
Tue, 22 Sep 2009 16:49:30 +0000 (18:49 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 22 Sep 2009 16:49:30 +0000 (18:49 +0200)
- fix solvable_lookup_str_poollang bug
- add support for REPOKEY_TYPE_BINARY
- do not add provides when extending susetags solvables
- fix susetags language handling in demo application

examples/solv.c
ext/repo_susetags.c
ext/repo_write.c
src/pool.c
src/repodata.c
src/repodata.h
src/repopack.h
src/solvable.c
src/transaction.c
tools/dumpsolv.c

index b4c5358..d0bced4 100644 (file)
@@ -1208,11 +1208,15 @@ susetags_add_ext(Repo *repo, Repodata *data)
     {
       if (strncmp(di.kv.str, "packages.", 9) != 0)
        continue;
+      if (!strcmp(di.kv.str + 9, "gz"))
+       continue;
       if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.'))
        continue;
       ext[0] = di.kv.str[9];
       ext[1] = di.kv.str[10];
       ext[2] = 0;
+      if (!strcmp(ext, "en"))
+       continue;
       if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype))
        continue;
       handle = repodata_new_handle(data);
@@ -1224,7 +1228,7 @@ susetags_add_ext(Repo *repo, Repodata *data)
          repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_DISKUSAGE);
          repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRNUMNUMARRAY);
        }
-      if (!strcmp(ext, "FL"))
+      else if (!strcmp(ext, "FL"))
        {
          repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_FILELIST);
          repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRSTRARRAY);
@@ -1538,8 +1542,21 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
          printf(" fetching\n");
          if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), iscompressed(filename), filechksum, filechksumtype, &badchecksum)) == 0)
            break;      /* hopeless */
-         repo_add_susetags(repo, fp, defvendor, 0, 0);
+         repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE);
          fclose(fp);
+         /* add default language */
+         filename = susetags_find(repo, "packages.en.gz", &filechksum, &filechksumtype);
+          if (!filename)
+           filename = susetags_find(repo, "packages.en", &filechksum, &filechksumtype);
+         if (filename)
+           {
+             if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), iscompressed(filename), filechksum, filechksumtype, &badchecksum)) != 0)
+               {
+                 repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES);
+                 fclose(fp);
+               }
+           }
+          repo_internalize(repo);
          data = repo_add_repodata(repo, 0);
          susetags_add_ext(repo, data);
          repodata_internalize(data);
index e148d85..d8daa7f 100644 (file)
@@ -22,6 +22,7 @@ struct parsedata {
   char *kind;
   Repo *repo;
   Repodata *data;
+  int flags;
   struct parsedata_common common;
   int last_found_source;
   char **share_with;
@@ -326,7 +327,7 @@ finish_solvable(struct parsedata *pd, Solvable *s, Id handle, Offset freshens)
 #if 1
   /* move file provides to filelist */
   /* relies on the fact that rpm inserts self-provides at the end */
-  if (s->provides)
+  if (s->provides && (pd->flags & REPO_EXTEND_SOLVABLES) == 0)
     {
       Id *p, *lastreal, did;
       const char *str, *sp;
@@ -480,6 +481,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int
   pd.repo = pd.common.repo = repo;
   pd.data = data;
   pd.common.pool = pool;
+  pd.flags = flags;
 
   linep = line;
   s = 0;
index 2f0d4e4..4fc4f49 100644 (file)
@@ -821,6 +821,11 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue
        id = cbdata->dirused[id];
        data_addid(xd, id);
        break;
+      case REPOKEY_TYPE_BINARY:
+       data_addid(xd, kv->num);
+       if (kv->num)
+         data_addblob(xd, (unsigned char *)kv->str, kv->num);
+       break;
       case REPOKEY_TYPE_DIRNUMNUMARRAY:
        id = kv->id;
        if (cbdata->owndirpool)
@@ -854,9 +859,6 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue
          {
            cbdata->current_sub++;
          }
-       else
-         {
-         }
        break;
       case REPOKEY_TYPE_FLEXARRAY:
        if (!kv->entry)
index dad0971..0b0648e 100644 (file)
@@ -957,14 +957,6 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
          if (ndone >= repo->nsolvables)
            break;
 
-         if (!repodata_precheck_keyname(data, SOLVABLE_FILELIST))
-           continue;
-         for (j = 1; j < data->nkeys; j++)
-           if (data->keys[j].name == SOLVABLE_FILELIST)
-             break;
-         if (j == data->nkeys)
-           continue;
-
          if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
            {
              map_empty(&cbd->providedids);
@@ -989,13 +981,14 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
                  continue;
                }
            }
-          else
+
+         if (!repodata_has_keyname(data, SOLVABLE_FILELIST))
+           continue;
+
+         if (data->start < provstart || data->end > provend)
            {
-             if (data->start < provstart || data->end > provend)
-               {
-                 map_empty(&cbd->providedids);
-                 provstart = provend = 0;
-               }
+             map_empty(&cbd->providedids);
+             provstart = provend = 0;
            }
 
          /* check if the data is incomplete */
index 1b657f7..e0072e6 100644 (file)
@@ -1940,6 +1940,35 @@ repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str)
   data->attrdatalen += l;
 }
 
+void
+repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len)
+{
+  Repokey key;
+  unsigned char *dp;
+
+  key.name = keyname;
+  key.type = REPOKEY_TYPE_BINARY;
+  key.size = 0;
+  key.storage = KEY_STORAGE_INCORE;
+  data->attrdata = sat_extend(data->attrdata, data->attrdatalen, len + 5, 1, REPODATA_ATTRDATA_BLOCK);
+  dp = data->attrdata + data->attrdatalen;
+  if (len >= (1 << 14))
+    {
+      if (len >= (1 << 28))
+        *dp++ = (len >> 28) | 128;
+      if (len >= (1 << 21))
+        *dp++ = (len >> 21) | 128;
+      *dp++ = (len >> 14) | 128;
+    }
+  if (len >= (1 << 7))
+    *dp++ = (len >> 7) | 128;
+  *dp++ = len & 127;
+  if (len)
+    memcpy(dp, buf, len);
+  repodata_set(data, solvid, &key, data->attrdatalen);
+  data->attrdatalen = dp + len - data->attrdata;
+}
+
 /* add an array element consisting of entrysize Ids to the repodata. modifies attriddata
  * so that the caller can append the new element there */
 static void
@@ -2260,7 +2289,7 @@ repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int ov
 
 /**********************************************************************/
 
-/* TODO: unify with repo_write! */
+/* TODO: unify with repo_write and repo_solv! */
 
 #define EXTDATA_BLOCK 1023
 
@@ -2273,6 +2302,7 @@ static void
 data_addid(struct extdata *xd, Id x)
 {
   unsigned char *dp;
+
   xd->buf = sat_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK);
   dp = xd->buf + xd->len;
 
@@ -2295,7 +2325,7 @@ data_addideof(struct extdata *xd, Id x, int eof)
 {
   if (x >= 64)
     x = (x & 63) | ((x & ~63) << 1);
-  data_addid(xd, (eof ? x: x | 64));
+  data_addid(xd, (eof ? x : x | 64));
 }
 
 static void
@@ -2350,6 +2380,14 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore,
     case REPOKEY_TYPE_DIR:
       data_addid(xd, val);
       break;
+    case REPOKEY_TYPE_BINARY:
+      {
+       Id len;
+       unsigned char *dp = data_read_id(data->attrdata + val, &len);
+       dp += len;
+       data_addblob(xd, data->attrdata + val, dp - (data->attrdata + val));
+      }
+      break;
     case REPOKEY_TYPE_IDARRAY:
       for (ida = data->attriddata + val; *ida; ida++)
        data_addideof(xd, ida[0], ida[1] ? 0 : 1);
index a7c5920..1f9fa6e 100644 (file)
@@ -155,6 +155,19 @@ repodata_precheck_keyname(Repodata *data, Id keyname)
   return x && (x & (1 << (keyname & 7))) ? 1 : 0;
 }
 
+/* check if the repodata contains data for the specified keyname */
+static inline int
+repodata_has_keyname(Repodata *data, Id keyname)
+{
+  int i;
+  if (!repodata_precheck_keyname(data, keyname))
+    return 0;
+  for (i = 1; i < data->nkeys; i++)
+    if (data->keys[i].name == keyname)
+      return 1;
+  return 0;
+}
+
 /* search key <keyname> (all keys, if keyname == 0) for Id <solvid>
  * Call <callback> for each match */
 void repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, struct _KeyValue *kv), void *cbdata);
@@ -200,6 +213,7 @@ void repodata_set_void(Repodata *data, Id solvid, Id keyname);
 void repodata_set_num(Repodata *data, Id solvid, Id keyname, unsigned int num);
 void repodata_set_id(Repodata *data, Id solvid, Id keyname, Id id);
 void repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str);
+void repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len);
 /* create id from string, then set_id */
 void repodata_set_poolstr(Repodata *data, Id solvid, Id keyname, const char *str);
 
index bfc1425..e55072c 100644 (file)
@@ -93,6 +93,10 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
     case REPOKEY_TYPE_SHA256:
       kv->str = (const char *)dp;
       return dp + SIZEOF_SHA256;
+    case REPOKEY_TYPE_BINARY:
+      dp = data_read_id(dp, &kv->num);
+      kv->str = (const char *)dp;
+      return dp + kv->num;
     case REPOKEY_TYPE_IDARRAY:
       return data_read_ideof(dp, &kv->id, &kv->eof);
     case REPOKEY_TYPE_DIRSTRARRAY:
@@ -146,6 +150,12 @@ data_skip(unsigned char *dp, int type)
       while ((*dp) != 0)
         dp++;
       return dp + 1;
+    case REPOKEY_TYPE_BINARY:
+      {
+       Id len;
+       dp = data_read_id(dp, &len);
+       return dp + len;
+      }
     case REPOKEY_TYPE_DIRSTRARRAY:
       for (;;)
         {
index dfe8ce1..26caf77 100644 (file)
@@ -74,6 +74,49 @@ solvable_lookup_str(Solvable *s, Id keyname)
 }
 
 const char *
+solvable_lookup_str_base(Solvable *s, Id keyname, Id basekeyname)
+{
+  Pool *pool;
+  const char *str, *basestr;
+  Id p, pp;
+  Solvable *s2;
+  int pass;
+
+  if (!s->repo)
+    return 0;
+  pool = s->repo->pool;
+  str = solvable_lookup_str(s, keyname);
+  if (str || keyname == basekeyname)
+    return str;
+  basestr = solvable_lookup_str(s, basekeyname);
+  if (!basestr)
+    return 0;
+  /* search for a solvable with same name and same base that has the
+   * translation */
+  if (!pool->whatprovides)
+    return 0;
+  /* we do this in two passes, first same vendor, then all other vendors */
+  for (pass = 0; pass < 2; pass++)
+    {
+      FOR_PROVIDES(p, pp, s->name)
+       {
+         s2 = pool->solvables + p;
+         if (s2->name != s->name)
+           continue;
+         if ((s->vendor == s2->vendor) != (pass == 0))
+           continue;
+         str = solvable_lookup_str(s2, basekeyname);
+         if (!str || strcmp(str, basestr))
+           continue;
+         str = solvable_lookup_str(s2, keyname);
+         if (str)
+           return str;
+       }
+    }
+  return 0;
+}
+
+const char *
 solvable_lookup_str_poollang(Solvable *s, Id keyname)
 {
   Pool *pool;
@@ -101,8 +144,8 @@ solvable_lookup_str_poollang(Solvable *s, Id keyname)
       if (i >= pool->languagecacheother)
        {
          pool->languagecache = sat_realloc2(pool->languagecache, pool->languagecacheother + 1, cols * sizeof(Id));
-         pool->languagecacheother++;
          row = pool->languagecache + cols * (ID_NUM_INTERNAL + pool->languagecacheother++);
+         *row = keyname;
        }
     }
   else
@@ -121,7 +164,7 @@ solvable_lookup_str_poollang(Solvable *s, Id keyname)
          *row = str2id(pool, p, 1);
           sat_free(p);
        }
-      str = solvable_lookup_str(s, *row);
+      str = solvable_lookup_str_base(s, *row, keyname);
       if (str)
        return str;
     }
@@ -135,7 +178,7 @@ solvable_lookup_str_lang(Solvable *s, Id keyname, const char *lang)
     {
       const char *str;
       Id id = pool_id2langid(s->repo->pool, keyname, lang, 0);
-      if (id && (str = solvable_lookup_str(s, id)) != 0)
+      if (id && (str = solvable_lookup_str_base(s, id, keyname)) != 0)
         return str;
     }
   return solvable_lookup_str(s, keyname);
index 2a481fa..4efc4da 100644 (file)
@@ -1228,6 +1228,9 @@ addsolvableedges(struct orderdata *od, Solvable *s)
                  if (s2->repo != installed && MAPTST(&trans->transactsmap, p2))
                    {
                      /* deinstall p before installing p2 */
+#if 0
+                     printf("add conflict uninst->inst edge (%s -> %s -> %s)\n", solvid2str(pool, p2), dep2str(pool, con), solvid2str(pool, p));
+#endif
                      addedge(od, p2, p, TYPE_CON);
                    }
                }
@@ -1236,6 +1239,9 @@ addsolvableedges(struct orderdata *od, Solvable *s)
                  if (s2->repo == installed && MAPTST(&trans->transactsmap, p2))
                    {
                      /* deinstall p2 before installing p */
+#if 0
+                     printf("add conflict uninst->inst edge (%s -> %s -> %s)\n", solvid2str(pool, p), dep2str(pool, con), solvid2str(pool, p2));
+#endif
                      addedge(od, p, p2, TYPE_CON);
                    }
                }
index 95a5730..061f3d0 100644 (file)
@@ -102,6 +102,12 @@ dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
     case REPOKEY_TYPE_CONSTANT:
       printf("%s: %d\n", keyname, kv->num);
       break;
+    case REPOKEY_TYPE_BINARY:
+      if (kv->num)
+        printf("%s: %02x..%02x len %d\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num);
+      else
+        printf("%s: len 0\n", keyname);
+      break;
     case REPOKEY_TYPE_DIRNUMNUMARRAY:
       if (!kv->entry)
         printf("%s:\n%*s", keyname, indent, "");