- more cleanups:
authorMichael Schroeder <mls@suse.de>
Mon, 20 Oct 2008 10:21:46 +0000 (10:21 +0000)
committerMichael Schroeder <mls@suse.de>
Mon, 20 Oct 2008 10:21:46 +0000 (10:21 +0000)
- add pool argument to datamatcher_init
- add flags argument to repodata_search
- only add sentinal if SEARCH_SENTINEL is specified
- use kv.eof == 2 for sentinel like before
- rename dataiterator_match to dataiterator_match_obsolete
- add repodata_stringify function
- make datamatcher match simple strings so it can be reused
- add dataiterator_prepend_keyname to match keyname pathes
- rename dataiterator_jump_to_solvable to dataiterator_jump_to_solvid

12 files changed:
package/libsatsolver.spec.in
src/knownid.h
src/pool.c
src/pool.h
src/repo.c
src/repo.h
src/repo_solv.c
src/repodata.c
src/repodata.h
tools/dumpsolv.c
tools/repo_rpmdb.c
tools/repo_write.c

index 407b288..3d404cf 100644 (file)
@@ -23,7 +23,7 @@ BuildRequires: expat-devel
 %endif
 BuildRequires:  cmake rpm-devel gcc-c++ ruby-devel swig perl python-devel
 # the testsuite uses the check framework
-BuildRequires:  check check-devel
+BuildRequires:  check-devel
 Summary:        A new approach to package dependency solving
 
 %description
index 77bf275..d74eb3e 100644 (file)
@@ -26,6 +26,9 @@ enum sat_knownid {
 
 KNOWNID(ID_NULL,                       "<NULL>"),
 KNOWNID(ID_EMPTY,                      ""),
+
+/* The following Ids are stored in the solvable and must
+ * come in one block */
 KNOWNID(SOLVABLE_NAME,                 "solvable:name"),
 KNOWNID(SOLVABLE_ARCH,                 "solvable:arch"),
 KNOWNID(SOLVABLE_EVR,                  "solvable:evr"),
@@ -39,6 +42,7 @@ KNOWNID(SOLVABLE_SUGGESTS,            "solvable:suggests"),
 KNOWNID(SOLVABLE_SUPPLEMENTS,          "solvable:supplements"),
 KNOWNID(SOLVABLE_ENHANCES,             "solvable:enhances"),
 KNOWNID(RPM_RPMDBID,                   "rpm:dbid"),
+
 /* normal requires before this, prereqs after this */
 KNOWNID(SOLVABLE_PREREQMARKER,         "solvable:prereqmarker"),
 /* normal provides before this, generated file provides after this */
@@ -119,12 +123,9 @@ KNOWNID(SOLVABLE_SOURCENAME,               "solvable:sourcename"),
 KNOWNID(SOLVABLE_SOURCEEVR,            "solvable:sourceevr"),
 KNOWNID(SOLVABLE_ISVISIBLE,            "solvable:isvisible"),
 KNOWNID(SOLVABLE_CHECKSUM,             "solvable:checksum"),
-/* pkgid: md5sum over header + payload */
-KNOWNID(SOLVABLE_PKGID,                        "solvable:pkgid"),
-/* hdrid: sha1sum over header only */
-KNOWNID(SOLVABLE_HDRID,                        "solvable:hdrid"),
-/* leadsigid: md5sum over lead + sigheader */
-KNOWNID(SOLVABLE_LEADSIGID,            "solvable:leadsigid"),
+KNOWNID(SOLVABLE_PKGID,                        "solvable:pkgid"),      /* pkgid: md5sum over header + payload */
+KNOWNID(SOLVABLE_HDRID,                        "solvable:hdrid"),      /* hdrid: sha1sum over header only */
+KNOWNID(SOLVABLE_LEADSIGID,            "solvable:leadsigid"),  /* leadsigid: md5sum over lead + sigheader */
 
 KNOWNID(SOLVABLE_PATCHCATEGORY,                "solvable:patchcategory"),
 KNOWNID(SOLVABLE_HEADEREND,            "solvable:headerend"),
index f954b82..7394be9 100644 (file)
@@ -885,7 +885,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
          if (data)
            {
              map_init(&providedids, pool->ss.nstrings);
-             repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addfileprovides_setid_cb, &providedids);
+             repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, 0, addfileprovides_setid_cb, &providedids);
              for (i = 0; i < cbd->nfiles; i++)
                if (!MAPTST(&providedids, cbd->ids[i]))
                  break;
@@ -1009,6 +1009,12 @@ pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callba
       repo_search(pool->solvables[p].repo, p, key, match, flags, callback, cbdata);
 }
 
+void
+pool_clear_pos(Pool *pool)
+{
+  memset(&pool->pos, 0, sizeof(pool->pos));
+}
+
 
 void
 pool_set_languages(Pool *pool, const char **languages, int nlanguages)
index 361041d..5ac2227 100644 (file)
@@ -45,6 +45,7 @@ struct _KeyValue;
 
 typedef struct _Repopos {
   struct _Repo *repo;
+  Id solvid;
   Id repodataid;
   Id schema;
   Id dp; 
@@ -270,6 +271,9 @@ static inline void pool_setloadcallback(Pool *pool, FILE *(*cb)(struct _Pool *,
  */
 void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
 
+void pool_clear_pos(Pool *pool);
+
+
 typedef struct _duchanges {
   const char *path;
   int kbytes;
index af7c402..c306292 100644 (file)
@@ -581,8 +581,13 @@ repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValu
 {
   struct matchdata *md = cbdata;
 
-  if (md->matcher.match && !datamatcher_match(&md->matcher, data, key, kv))
-    return 0;
+  if (md->matcher.match)
+    {
+      if (!repodata_stringify(md->pool, data, key, kv, md->flags))
+       return 0;
+      if (!datamatcher_match(&md->matcher, kv->str))
+       return 0;
+    }
   md->stop = md->callback(md->callback_data, s, data, key, kv);
   return md->stop;
 }
@@ -762,7 +767,7 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
        }
       if (data->state == REPODATA_ERROR)
        continue;
-      repodata_search(data, p, keyname, repo_matchvalue, md);
+      repodata_search(data, p, keyname, md->flags, repo_matchvalue, md);
       if (md->stop > SEARCH_NEXT_KEY)
        break;
     }
@@ -779,7 +784,7 @@ repo_search(Repo *repo, Id p, Id keyname, const char *match, int flags, int (*ca
   md.callback = callback;
   md.callback_data = cbdata;
   if (match)
-    datamatcher_init(&md.matcher, md.pool, match, flags);
+    datamatcher_init(&md.matcher, match, flags);
   repo_search_md(repo, p, keyname, &md);
   if (match)
     datamatcher_free(&md.matcher);
index 4f801c1..0e83522 100644 (file)
@@ -44,8 +44,7 @@ typedef struct _Repo {
   int idarraysize;
   Offset lastoff;
 
-  Id *rpmdbid;                 /* hmm, go to repodata? */
-  unsigned char rpmdbcookie[32];
+  Id *rpmdbid;                 /* solvable side data */
 
   Repodata *repodata;          /* our stores for non-solvable related data */
   unsigned nrepodata;          /* number of our stores..  */
@@ -142,6 +141,7 @@ static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int
 #define SEARCH_NEXT_KEY         1
 #define SEARCH_NEXT_SOLVABLE    2
 #define SEARCH_STOP             3
+#define SEARCH_ENTERSUB                -1
 
 typedef struct _KeyValue {
   Id id;
@@ -166,7 +166,7 @@ typedef struct _KeyValue {
 #define        SEARCH_NOCASE                   (1<<8)
 #define        SEARCH_NO_STORAGE_SOLVABLE      (1<<9)
 #define SEARCH_SUB                     (1<<10)
-#define SEARCH_ALL_REPOS               (1<<11)
+#define SEARCH_ARRAYSENTINEL           (1<<11)
 #define SEARCH_SKIP_KIND               (1<<12)
 
 
@@ -223,7 +223,6 @@ typedef struct _Dataiterator
 #else
 
 typedef struct _Datamatcher {
-  Pool *pool;
   int flags;
   void *match;
   int error;
@@ -264,35 +263,40 @@ typedef struct _Dataiterator
     Id *keyp;
   } parents[3];
   int nparents;
+  Id keynames[3 + 1];
+  int nkeynames;
+
 } Dataiterator;
 
 #endif
 
-void datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags);
+int datamatcher_init(Datamatcher *ma, const char *match, int flags);
 void datamatcher_free(Datamatcher *ma);
-int datamatcher_match(Datamatcher *ma, Repodata *data, Repokey *key, KeyValue *kv);
+int datamatcher_match(Datamatcher *ma, const char *str);
 
 /* Use these like:
      Dataiterator di;
-     dataiterator_init(&di, repo, 0, 0, "bla", SEARCH_SUBSTRING);
+     dataiterator_init(&di, repo->pool, repo, 0, 0, "bla", SEARCH_SUBSTRING);
      while (dataiterator_step(&di))
        dosomething(di.solvid, di.key, di.kv);
      dataiterator_free(&di);   */
-void dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
+int dataiterator_init(Dataiterator *di, Pool *pool, Repo *repo, Id p, Id keyname,
                       const char *match, int flags);
+void dataiterator_prepend_keyname(Dataiterator *di, Id keyname);
 void dataiterator_free(Dataiterator *di);
 int dataiterator_step(Dataiterator *di);
 void dataiterator_setpos(Dataiterator *di);
 void dataiterator_setpos_parent(Dataiterator *di);
-int dataiterator_match(Dataiterator *di, int flags, const void *match);
+int dataiterator_match(Dataiterator *di, Datamatcher *ma);
 void dataiterator_skip_attribute(Dataiterator *di);
 void dataiterator_skip_solvable(Dataiterator *di);
 void dataiterator_skip_repo(Dataiterator *di);
-void dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s);
+void dataiterator_jump_to_solvid(Dataiterator *di, Id solvid);
 void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo);
+void dataiterator_entersub(Dataiterator *di);
 
 /* to be removed ... */
-int dataiterator_match(Dataiterator *di, int flags, const void *match);
+int dataiterator_match_obsolete(Dataiterator *di, int flags, const void *match);
 
 void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
 void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
index 518378c..cb7d21f 100644 (file)
@@ -430,12 +430,12 @@ create_stub_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue
            }
          stubdata->data = 0;
        }
-      if (kv->eof)
+      if (kv->eof == 2)
        return SEARCH_NEXT_SOLVABLE;
       stubdata->data = repo_add_repodata(data->repo, 0);
       stubdata->data->state = REPODATA_STUB;
       stubdata->data->loadcallback = repodata_load_stub;
-      return 0;
+      return SEARCH_ENTERSUB;
     }
   if (!stubdata->data)
     return SEARCH_NEXT_KEY;
@@ -1328,7 +1328,7 @@ printf("=> %s %s %p\n", id2str(pool, keys[key].name), id2str(pool, keys[key].typ
       struct create_stub_data stubdata;
       /* got some */
       memset(&stubdata, 0, sizeof(stubdata));
-      repodata_search(&data, SOLVID_META, REPOSITORY_EXTERNAL, create_stub_cb, &stubdata);
+      repodata_search(&data, SOLVID_META, REPOSITORY_EXTERNAL, SEARCH_ARRAYSENTINEL, create_stub_cb, &stubdata);
     }
   return 0;
 }
index ae4d470..8e2c88b 100644 (file)
@@ -611,6 +611,44 @@ repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep)
  * data search
  */
 
+
+int
+repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int flags)
+{
+  switch (key->type)
+    {
+    case REPOKEY_TYPE_ID:
+    case REPOKEY_TYPE_CONSTANTID:
+    case REPOKEY_TYPE_IDARRAY:
+      if (data && data->localpool)
+       kv->str = stringpool_id2str(&data->spool, kv->id);
+      else
+       kv->str = id2str(pool, kv->id);
+      if ((flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
+       {
+         const char *s = strchr(kv->str, ':');
+         if (s)
+           kv->str = s + 1;
+       }
+      return 1;
+    case REPOKEY_TYPE_STR:
+      return 1;
+    case REPOKEY_TYPE_DIRSTRARRAY:
+      if (!(flags & SEARCH_FILES))
+       return 1;       /* match just the basename */
+      /* Put the full filename into kv->str.  */
+      kv->str = repodata_dir2str(data, kv->id, kv->str);
+      /* And to compensate for that put the "empty" directory into
+        kv->id, so that later calls to repodata_dir2str on this data
+        come up with the same filename again.  */
+      kv->id = 0;
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+
 struct subschema_data {
   Solvable *s;
   void *cbdata;
@@ -619,7 +657,7 @@ struct subschema_data {
 
 /* search a specific repodata */
 void
-repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
+repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
 {
   Id schema;
   Repokey *key;
@@ -686,6 +724,8 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbd
          kv.eof = 0;
           while (ddp && nentries > 0)
            {
+             if (!--nentries)
+               kv.eof = 1;
              if (key->type == REPOKEY_TYPE_FLEXARRAY || !kv.entry)
                ddp = data_read_id(ddp, &schema);
              kv.id = schema;
@@ -693,18 +733,17 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbd
              stop = callback(cbdata, s, data, key, &kv);
              if (stop > SEARCH_NEXT_KEY)
                return;
-             if (stop)
+             if (stop && stop != SEARCH_ENTERSUB)
                break;
-             if (!keyname)
-               repodata_search(data, SOLVID_SUBSCHEMA, 0, callback, &subd);
+             if ((flags & SEARCH_SUB) != 0 || stop == SEARCH_ENTERSUB)
+               repodata_search(data, SOLVID_SUBSCHEMA, 0, flags, callback, &subd);
              ddp = data_skip_schema(data, ddp, schema);
-             nentries--;
              kv.entry++;
            }
-         if (!nentries)
+         if (!nentries && (flags & SEARCH_ARRAYSENTINEL) != 0)
            {
              /* sentinel */
-             kv.eof = 1;
+             kv.eof = 2;
              kv.str = (char *)ddp;
              stop = callback(cbdata, s, data, key, &kv);
              if (stop > SEARCH_NEXT_KEY)
@@ -734,15 +773,10 @@ repodata_setpos_kv(Repodata *data, KeyValue *kv)
 {
   Pool *pool = data->repo->pool;
   if (!kv)
-    {
-      pool->pos.repo = 0;
-      pool->pos.repodataid = 0;
-      pool->pos.dp = 0;
-      pool->pos.schema = 0;
-    }
+    pool_clear_pos(pool);
   else
     {
-      pool->pos.repo = 0;
+      pool->pos.repo = data->repo;
       pool->pos.repodataid = data - data->repo->repodata;
       pool->pos.dp = (unsigned char *)kv->str - data->incoredata;
       pool->pos.schema = kv->id;
@@ -819,10 +853,9 @@ solvabledata_fetch(Solvable *s, KeyValue *kv, Id keyname)
     }
 }
 
-void
-datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags)
+int
+datamatcher_init(Datamatcher *ma, const char *match, int flags)
 {
-  ma->pool = pool;
   ma->match = (void *)match;
   ma->flags = flags;
   ma->error = 0;
@@ -837,6 +870,7 @@ datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags)
          ma->flags = (flags & ~SEARCH_STRINGMASK) | SEARCH_ERROR;
        }
     }
+  return ma->error;
 }
 
 void
@@ -850,72 +884,40 @@ datamatcher_free(Datamatcher *ma)
 }
 
 int
-datamatcher_match(Datamatcher *ma, Repodata *data, Repokey *key, KeyValue *kv)
+datamatcher_match(Datamatcher *ma, const char *str)
 {
-  switch (key->type)
-    {
-    case REPOKEY_TYPE_ID:
-    case REPOKEY_TYPE_IDARRAY:
-      if (data && data->localpool)
-       kv->str = stringpool_id2str(&data->spool, kv->id);
-      else
-       kv->str = id2str(ma->pool, kv->id);
-      break;
-    case REPOKEY_TYPE_STR:
-      break;
-    case REPOKEY_TYPE_DIRSTRARRAY:
-      if (!(ma->flags & SEARCH_FILES))
-       return 0;
-      /* Put the full filename into kv->str.  */
-      kv->str = repodata_dir2str(data, kv->id, kv->str);
-      /* And to compensate for that put the "empty" directory into
-        kv->id, so that later calls to repodata_dir2str on this data
-        come up with the same filename again.  */
-      kv->id = 0;
-      break;
-    default:
-      return 0;
-    }
-  /* Maybe skip the kind specifier.  Do this only for SOLVABLE attributes,
-     for the others we can't know if a colon separates a kind or not.  */
-  if ((ma->flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
-    {
-      const char *s = strchr(kv->str, ':');
-      if (s)
-       kv->str = s + 1;
-    }
   switch ((ma->flags & SEARCH_STRINGMASK))
     {
     case SEARCH_SUBSTRING:
       if (ma->flags & SEARCH_NOCASE)
        {
-         if (!strcasestr(kv->str, (const char *)ma->match))
+         if (!strcasestr(str, (const char *)ma->match))
            return 0;
        }
       else
        {
-         if (!strstr(kv->str, (const char *)ma->match))
+         if (!strstr(str, (const char *)ma->match))
            return 0;
        }
       break;
     case SEARCH_STRING:
       if (ma->flags & SEARCH_NOCASE)
        {
-         if (strcasecmp((const char *)ma->match, kv->str))
+         if (strcasecmp((const char *)ma->match, str))
            return 0;
        }
       else
        {
-         if (strcmp((const char *)ma->match, kv->str))
+         if (strcmp((const char *)ma->match, str))
            return 0;
        }
       break;
     case SEARCH_GLOB:
-      if (fnmatch((const char *)ma->match, kv->str, (ma->flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0))
+      if (fnmatch((const char *)ma->match, str, (ma->flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0))
        return 0;
       break;
     case SEARCH_REGEX:
-      if (regexec((const regex_t *)ma->match, kv->str, 0, NULL, 0))
+      if (regexec((const regex_t *)ma->match, str, 0, NULL, 0))
        return 0;
       break;
     default:
@@ -930,6 +932,7 @@ enum {
   di_enterrepo,
   di_entersolvable,
   di_enterrepodata,
+  di_enterschema,
   di_enterkey,
 
   di_nextattr,
@@ -949,36 +952,55 @@ enum {
   di_entersolvablekey
 };
 
-void
-dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname, const char *match, int flags)
+int
+dataiterator_init(Dataiterator *di, Pool *pool, Repo *repo, Id p, Id keyname, const char *match, int flags)
 {
   memset(di, 0, sizeof(*di));
-  di->repo = repo;
-  di->keyname = keyname;
-  di->solvid = p;
-  di->pool = repo->pool;
-  if (p)
-    flags |= SEARCH_THISSOLVID;
-  di->flags = flags;
-  if (repo && !(flags & SEARCH_ALL_REPOS))
-    di->repoid = -1;
-  else
-    di->repo = di->pool->repos[0];
+  di->pool = pool;
   if (match)
-    datamatcher_init(&di->matcher, di->pool, match, flags);
-  if (p == SOLVID_POS)
     {
-      di->repo = di->pool->pos.repo;
-      if (!di->repo)
+      int error;
+      if ((error = datamatcher_init(&di->matcher, match, flags)) != 0)
        {
          di->state = di_bye;
-         return;
+         return error;
        }
-      di->data = di->repo->repodata + di->pool->pos.repodataid;
-      di->repoid = -1;
-      di->repodataid = -1;
     }
-  di->state = di_enterrepo;
+  di->repo = repo;
+  di->keyname = keyname;
+  di->keynames[0] = keyname;
+  di->flags = flags & ~SEARCH_THISSOLVID;
+  if (!pool->nrepos)
+    {
+      di->state = di_bye;
+      return 0;
+    }
+  if (repo)
+    di->repoid = -1;
+  if (p)
+    dataiterator_jump_to_solvid(di, p);
+  else
+    {
+      di->repo = pool->repos[0];
+      di->state = di_enterrepo;
+    }
+  return 0;
+}
+
+void
+dataiterator_prepend_keyname(Dataiterator *di, Id keyname)
+{
+  int i;
+
+  if (di->nkeynames >= sizeof(di->keynames)/sizeof(*di->keynames) - 2)
+    {
+      di->state = di_bye;      /* sorry */
+      return;
+    }
+  for (i = di->nkeynames + 1; i > 0; i--)
+    di->keynames[i] = di->keynames[i - 1];
+  di->keynames[0] = di->keyname = keyname;
+  di->nkeynames++;
 }
 
 void
@@ -995,20 +1017,9 @@ dataiterator_find_keyname(Dataiterator *di, Id keyname)
   Repokey *keys = di->data->keys;
   unsigned char *dp;
 
-  if (!(di->flags & SEARCH_SUB))
-    {
-      for (keyp = di->keyp; *keyp; keyp++)
-       if (keys[*keyp].name == di->keyname)
-         break;
-    }
-  else
-    {
-      for (keyp++; *keyp; keyp++)
-       if (keys[*keyp].name == di->keyname || 
-           keys[*keyp].type == REPOKEY_TYPE_FIXARRAY || 
-           keys[*keyp].type == REPOKEY_TYPE_FLEXARRAY)
-         break;
-    }
+  for (keyp = di->keyp; *keyp; keyp++)
+    if (keys[*keyp].name == keyname)
+      break;
   if (!*keyp)
     return 0;
   dp = forward_to_key(di->data, *keyp, di->keyp, di->dp);
@@ -1029,13 +1040,16 @@ dataiterator_step(Dataiterator *di)
        {
        case di_enterrepo: di_enterrepo:
          if (!(di->flags & SEARCH_THISSOLVID))
-           di->solvid = di->repo->start;
+           {
+             di->solvid = di->repo->start - 1; /* reset solvid iterator */
+             goto di_nextsolvable;
+           }
          /* FALLTHROUGH */
 
        case di_entersolvable: di_entersolvable:
          if (di->repodataid >= 0)
            {
-             di->repodataid = 0;
+             di->repodataid = 0;       /* reset repodata iterator */
              if (di->solvid > 0 && !(di->flags & SEARCH_NO_STORAGE_SOLVABLE) && (!di->keyname || (di->keyname >= SOLVABLE_NAME && di->keyname <= RPM_RPMDBID)))
                {
                  di->key = solvablekeys + (di->keyname ? di->keyname - SOLVABLE_NAME : 0);
@@ -1057,12 +1071,18 @@ dataiterator_step(Dataiterator *di)
          di->dp = solvid2data(di->data, di->solvid, &schema);
          if (!di->dp)
            goto di_nextrepodata;
+         /* reset key iterator */
          di->keyp = di->data->schemadata + di->data->schemata[schema];
+         /* FALLTHROUGH */
+
+       case di_enterschema: di_enterschema:
          if (di->keyname)
+           di->dp = dataiterator_find_keyname(di, di->keyname);
+         if (!di->dp || !*di->keyp)
            {
-             di->dp = dataiterator_find_keyname(di, di->keyname);
-             if (!di->dp)
-               goto di_nextrepodata;
+             if (di->kv.parent)
+               goto di_leavesub;
+             goto di_nextrepodata;
            }
          /* FALLTHROUGH */
 
@@ -1074,6 +1094,8 @@ dataiterator_step(Dataiterator *di)
            goto di_nextkey;
          if (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY)
            goto di_enterarray;
+         if (di->nparents < di->nkeynames)
+           goto di_nextkey;
          /* FALLTHROUGH */
 
        case di_nextattr:
@@ -1086,17 +1108,8 @@ dataiterator_step(Dataiterator *di)
          break;
 
        case di_nextkey: di_nextkey:
-         if (!di->keyname)
-           {
-             if (*++di->keyp)
-               goto di_enterkey;
-           }
-         else if ((di->flags & SEARCH_SUB) != 0)
-           {
-             di->dp = dataiterator_find_keyname(di, di->keyname);
-             if (di->dp)
-               goto di_enterkey;
-           }
+         if (!di->keyname && *++di->keyp)
+           goto di_enterkey;
          if (di->kv.parent)
            goto di_leavesub;
          /* FALLTHROUGH */
@@ -1138,6 +1151,8 @@ dataiterator_step(Dataiterator *di)
          return 0;
 
        case di_enterarray: di_enterarray:
+         if (di->key->name == REPOSITORY_SOLVABLES)
+           goto di_nextkey;
          di->ddp = data_read_id(di->ddp, &di->kv.num);
          di->kv.eof = 0;
          di->kv.entry = -1;
@@ -1149,17 +1164,21 @@ dataiterator_step(Dataiterator *di)
            di->ddp = data_skip_schema(di->data, di->ddp, di->kv.id);
          if (di->kv.entry == di->kv.num)
            {
-             if (di->keyname && di->key->name != di->keyname)
+             if (di->nparents < di->nkeynames)
+               goto di_nextkey;
+             if (!(di->flags & SEARCH_ARRAYSENTINEL))
                goto di_nextkey;
              di->kv.str = (char *)di->ddp;
-             di->kv.eof = 1;
+             di->kv.eof = 2;
              di->state = di_nextkey;
              break;
            }
+         if (di->kv.entry == di->kv.num - 1)
+           di->kv.eof = 1;
          if (di->key->type == REPOKEY_TYPE_FLEXARRAY || !di->kv.entry)
            di->ddp = data_read_id(di->ddp, &di->kv.id);
          di->kv.str = (char *)di->ddp;
-         if (di->keyname && di->key->name != di->keyname)
+         if (di->nparents < di->nkeynames)
            goto di_entersub;
          if ((di->flags & SEARCH_SUB) != 0)
            di->state = di_entersub;
@@ -1178,8 +1197,8 @@ dataiterator_step(Dataiterator *di)
          memset(&di->kv, 0, sizeof(di->kv));
          di->kv.parent = &di->parents[di->nparents].kv;
          di->nparents++;
-         di->keyp--;
-         goto di_nextkey;
+         di->keyname = di->keynames[di->nparents];
+         goto di_enterschema;
 
        case di_leavesub: di_leavesub:
          di->nparents--;
@@ -1188,6 +1207,7 @@ dataiterator_step(Dataiterator *di)
          di->keyp = di->parents[di->nparents].keyp;
          di->key = di->data->keys + *di->keyp;
          di->ddp = (unsigned char *)di->kv.str;
+         di->keyname = di->keynames[di->nparents];
          goto di_nextarrayelement;
 
         /* special solvable attr handling follows */
@@ -1225,8 +1245,16 @@ dataiterator_step(Dataiterator *di)
        }
 
       if (di->matcher.match)
-       if (!datamatcher_match(&di->matcher, di->data, di->key, &di->kv))
+       {
+         if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags))
+           {
+             if (di->keyname && (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY))
+               return 1;
+             continue;
+           }
+         if (!datamatcher_match(&di->matcher, di->kv.str))
          continue;
+       }
       /* found something! */
       return 1;
     }
@@ -1244,9 +1272,10 @@ dataiterator_setpos(Dataiterator *di)
 {
   if (di->kv.eof)
     {
-      memset(&di->pool->pos, 0, sizeof(di->pool->pos));
+      pool_clear_pos(di->pool);
       return;
     }
+  di->pool->pos.solvid = di->solvid;
   di->pool->pos.repo = di->repo;
   di->pool->pos.repodataid = di->data - di->repo->repodata;
   di->pool->pos.schema = di->kv.id;
@@ -1258,9 +1287,10 @@ dataiterator_setpos_parent(Dataiterator *di)
 {
   if (!di->kv.parent)
     {
-      memset(&di->pool->pos, 0, sizeof(di->pool->pos));
+      pool_clear_pos(di->pool);
       return;
     }
+  di->pool->pos.solvid = di->solvid;
   di->pool->pos.repo = di->repo;
   di->pool->pos.repodataid = di->data - di->repo->repodata;
   di->pool->pos.schema = di->kv.parent->id;
@@ -1289,30 +1319,78 @@ dataiterator_skip_repo(Dataiterator *di)
 }
 
 void
-dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s)
+dataiterator_jump_to_solvid(Dataiterator *di, Id solvid)
 {
-  di->repo = s->repo;
-  di->repoid = -1;
-  di->solvid = s - di->pool->solvables;
+  di->nparents = 0;
+  if (solvid == SOLVID_POS)
+    {
+      di->repo = di->pool->pos.repo;
+      if (!di->repo)
+       {
+         di->state = di_bye;
+         return;
+       }
+      di->repoid = -1;
+      di->data = di->repo->repodata + di->pool->pos.repodataid;
+      di->repodataid = -1;
+      di->solvid = di->pool->pos.solvid;
+      di->state = di_enterrepo;
+      di->flags |= SEARCH_THISSOLVID;
+      return;
+    }
+  if (solvid > 0)
+    {
+      di->repo = di->pool->solvables[solvid].repo;
+      di->repoid = -1;
+    }
+  else if (di->repoid >= 0)
+    {
+      if (!di->pool->nrepos)
+       {
+         di->state = di_bye;
+         return;
+       }
+      di->repo = di->pool->repos[0];
+      di->repoid = 0;
+    }
+  di->repodataid = 0;
+  di->solvid = solvid;
+  if (solvid)
+    di->flags |= SEARCH_THISSOLVID;
   di->state = di_entersolvable;
 }
 
 void
 dataiterator_jump_to_repo(Dataiterator *di, Repo *repo)
 {
+  di->nparents = 0;
   di->repo = repo;
   di->repoid = -1;
+  di->repodataid = 0;
+  di->solvid = 0;
+  di->flags &= ~SEARCH_THISSOLVID;
   di->state = di_enterrepo;
 }
 
 int
-dataiterator_match(Dataiterator *di, int flags, const void *vmatch)
+dataiterator_match(Dataiterator *di, Datamatcher *ma)
 {
-  Datamatcher matcher = di->matcher;
+  if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags))
+    return 0;
+  return datamatcher_match(ma, di->kv.str);
+}
+
+int
+dataiterator_match_obsolete(Dataiterator *di, int flags, const void *vmatch)
+{
+  Datamatcher matcher;
+
+  if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, flags))
+    return 0;
+  matcher = di->matcher;
   matcher.flags = flags;
   matcher.match = (void *)vmatch;
-  matcher.pool = di->pool;
-  return datamatcher_match(&matcher, di->data, di->key, &di->kv);
+  return datamatcher_match(&matcher, di->kv.str);
 }
 
 
index 79c298e..0c49953 100644 (file)
@@ -126,7 +126,9 @@ repodata_precheck_keyname(Repodata *data, Id keyname)
 /* 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 (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
+void repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
+int repodata_stringify(Pool *pool, Repodata *data, struct _Repokey *key, struct _KeyValue *kv, int flags);
+
 
 /* lookup functions */
 Id repodata_lookup_id(Repodata *data, Id solvid, Id keyname);
index 211ebcf..aad1d24 100644 (file)
@@ -18,22 +18,12 @@ static int with_attr = 0;
 static int dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv);
 
 static void
-dump_repodata (Repo *repo)
+dump_repodata(Repo *repo)
 {
   unsigned i;
   Repodata *data;
   if (repo->nrepodata == 0)
     return;
-  for (i = 0; i < 32; i++)
-    if (repo->rpmdbcookie[i])
-      break;
-  if (i < 32)
-    {
-      printf("rpmdb cookie: ");
-      for (i = 0; i < 32; i++)
-       printf("%02x", repo->rpmdbcookie[i]);
-      printf("\n");
-    }
   printf("repo contains %d repodata sections:\n", repo->nrepodata);
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     {
@@ -46,11 +36,12 @@ dump_repodata (Repo *repo)
       if (data->dirpool.ndirs)
        printf("  localpool has %d directories\n", data->dirpool.ndirs);
       printf("\n");
-      repodata_search(data, SOLVID_META, 0, dump_repoattrs_cb, 0);
+      repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repoattrs_cb, 0);
     }
   printf("\n");
 }
 
+#if 0
 static void
 printids(Repo *repo, char *kind, Offset ido)
 {
@@ -63,6 +54,7 @@ printids(Repo *repo, char *kind, Offset ido)
   while((id = *ids++) != 0)
     printf("  %s\n", dep2str(pool, id));
 }
+#endif
 
 int
 dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
@@ -151,11 +143,11 @@ dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
 void
 dump_repoattrs(Repo *repo, Id p)
 {
-#if 1
-  repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0);
+#if 0
+  repo_search(repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repoattrs_cb, 0);
 #else
   Dataiterator di;
-  dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
+  dataiterator_init(&di, repo->pool, repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB);
   while (dataiterator_step(&di))
     dump_attr(repo, di.data, di.key, &di.kv);
 #endif
@@ -309,6 +301,7 @@ int main(int argc, char **argv)
            continue;
          printf("\n");
          printf("solvable %d (%d):\n", n, i);
+#if 0
          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));
          if (s->vendor)
@@ -326,6 +319,7 @@ int main(int argc, char **argv)
 #if 0
          dump_attrs (repo, n - 1);
 #endif
+#endif
          dump_repoattrs(repo, i);
 #if 0
          dump_some_attrs(repo, s);
@@ -333,16 +327,6 @@ int main(int argc, char **argv)
          n++;
        }
 #if 0
-      for (i = 0; i < repo->nextra; i++)
-       {
-         printf("\nextra %d:\n", i);
-         Dataiterator di;
-         dataiterator_init(&di, repo, -1 - i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
-         while (dataiterator_step(&di))
-           dump_attr(repo, di.data, di.key, &di.kv);
-       }
-#endif
-#if 0
       tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
       printf("\n");
       tryme(repo, 0, 0, 0, 0);
@@ -353,7 +337,7 @@ int main(int argc, char **argv)
 #if 0
   printf ("\nSearchresults:\n");
   Dataiterator di;
-  dataiterator_init(&di, pool->repos[0], 0, 0, "3", SEARCH_EXTRA | SEARCH_SUBSTRING | SEARCH_ALL_REPOS | SEARCH_FILES);
+  dataiterator_init(&di, pool, 0, 0, 0, "3", SEARCH_SUB | SEARCH_SUBSTRING | SEARCH_FILES);
   //int count = 0;
   while (dataiterator_step(&di))
     {
index f5c74d3..e7818f7 100644 (file)
@@ -73,6 +73,7 @@
 #define TAG_DIRNAMES           1118
 #define TAG_PAYLOADFORMAT      1124
 #define TAG_PATCHESNAME         1133
+#define TAG_FILECOLORS         1140
 #define TAG_SUGGESTSNAME       1156
 #define TAG_SUGGESTSVERSION    1157
 #define TAG_SUGGESTSFLAGS      1158
index 107a166..1dcd5da 100644 (file)
@@ -709,7 +709,7 @@ repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Rep
       case REPOKEY_TYPE_FLEXARRAY:
        if (kv->entry == 0)
          {
-           if (!kv->eof)
+           if (kv->eof != 2)
              *cbdata->sp++ = 0;        /* mark start */
          }
        else
@@ -721,7 +721,7 @@ repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Rep
              sp--;
            cbdata->subschemata = sat_extend(cbdata->subschemata, cbdata->nsubschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
            cbdata->subschemata[cbdata->nsubschemata++] = addschema(cbdata, sp);
-           cbdata->sp = kv->eof ? sp - 1: sp;
+           cbdata->sp = kv->eof == 2 ? sp - 1: sp;
          }
        break;
       default:
@@ -860,7 +860,7 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue
       case REPOKEY_TYPE_FLEXARRAY:
        if (!kv->entry)
          data_addid(xd, kv->num);
-       if (!kv->eof)
+       if (kv->eof != 2)
          data_addid(xd, cbdata->subschemata[cbdata->current_sub++]);
        if (xd == cbdata->extdata + 0 && !kv->parent && !cbdata->doingsolvables)
          {
@@ -1260,7 +1260,7 @@ for (i = 1; i < cbdata.nmykeys; i++)
   /* collect all other data from all repodatas */
   /* XXX: merge arrays of equal keys? */
   for (j = 0, data = repo->repodata; j < repo->nrepodata; j++, data++)
-    repodata_search(data, SOLVID_META, 0, repo_write_cb_needed, &cbdata);
+    repodata_search(data, SOLVID_META, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_needed, &cbdata);
   sp = cbdata.sp;
   /* add solvables if needed */
   if (repo->nsolvables)
@@ -1357,7 +1357,7 @@ for (i = 1; i < cbdata.nmykeys; i++)
                continue;
              if (i < data->start || i >= data->end)
                continue;
-             repodata_search(data, i, 0, repo_write_cb_needed, &cbdata);
+             repodata_search(data, i, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_needed, &cbdata);
              needid = cbdata.needid;
            }
        }
@@ -1583,7 +1583,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
 
 #if 1
   for (j = 0, data = repo->repodata; j < repo->nrepodata; j++, data++)
-    repodata_search(data, SOLVID_META, 0, repo_write_cb_adddata, &cbdata);
+    repodata_search(data, SOLVID_META, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_adddata, &cbdata);
 #endif
 
   if (xd->len - cbdata.lastlen > cbdata.maxdata)
@@ -1633,7 +1633,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
                continue;
              if (i < data->start || i >= data->end)
                continue;
-             repodata_search(data, i, 0, repo_write_cb_adddata, &cbdata);
+             repodata_search(data, i, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_adddata, &cbdata);
            }
        }
       if (xd->len - cbdata.lastlen > cbdata.maxdata)