- fix mem leaks
authorMichael Schroeder <mls@suse.de>
Mon, 3 Mar 2008 19:56:59 +0000 (19:56 +0000)
committerMichael Schroeder <mls@suse.de>
Mon, 3 Mar 2008 19:56:59 +0000 (19:56 +0000)
- do not close fd 0 by mistake
- add repodata_lookup_void
- add solvable_lookup_void
- add solvable_get_location

src/CMakeLists.txt
src/pool.c
src/pool.h
src/repo_solv.c
src/repodata.c
src/repodata.h
src/solvable.c [new file with mode: 0644]

index db14219..545a8d9 100644 (file)
@@ -1,6 +1,6 @@
 
 SET(libsatsolver_SRCS bitmap.c  poolarch.c  poolvendor.c  poolid.c strpool.c dirpool.c
-solver.c repo_solv.c repo_helix.c evr.c pool.c queue.c   repo.c  repodata.c util.c policy.c fastlz.c)
+solver.c repo_solv.c repo_helix.c evr.c pool.c queue.c   repo.c  repodata.c util.c policy.c fastlz.c solvable.c)
 
 ADD_LIBRARY(satsolver STATIC ${libsatsolver_SRCS})
 
index a7298b2..d5cac2b 100644 (file)
@@ -163,6 +163,7 @@ pool_free(Pool *pool)
   for (i = 0; i < pool->nlanguages; i++)
     free((char *)pool->languages[i]);
   sat_free(pool->languages);
+  sat_free(pool->languagecache);
   sat_free(pool);
 }
 
@@ -932,58 +933,4 @@ pool_set_languages(Pool *pool, const char **languages, int nlanguages)
     pool->languages[i] = strdup(languages[i]);
 }
 
-const char *
-solvable_lookup_str_lang(Solvable *s, Id keyname)
-{
-  Pool *pool;
-  int i, cols;
-  const char *str;
-  Id *row;
-
-  if (!s->repo)
-    return repo_lookup_str(s, keyname);
-  pool = s->repo->pool;
-  if (!pool->nlanguages)
-    return repo_lookup_str(s, keyname);
-  cols = pool->nlanguages + 1;
-  if (!pool->languagecache)
-    {
-      pool->languagecache = sat_calloc(cols * ID_NUM_INTERNAL, sizeof(Id));
-      pool->languagecacheother = 0;
-    }
-  if (keyname >= ID_NUM_INTERNAL)
-    {
-      row = pool->languagecache + ID_NUM_INTERNAL * cols;
-      for (i = 0; i < pool->languagecacheother; i++, row += cols)
-       if (*row == keyname)
-         break;
-      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++);
-       }
-    }
-  else
-    row = pool->languagecache + keyname * cols;
-  row++;       /* skip keyname */
-  for (i = 0; i < pool->nlanguages; i++, row++)
-    {
-      if (!*row)
-       {
-         char *p;
-         const char *kn;
-
-         kn = id2str(pool, keyname);
-          p = sat_malloc(strlen(kn) + strlen(pool->languages[i]) + 2);
-         sprintf(p, "%s:%s", kn, pool->languages[i]);
-         *row = str2id(pool, p, 1);
-       }
-      str = repo_lookup_str(s, *row);
-      if (str)
-       return str;
-    }
-  return repo_lookup_str(s, keyname);
-}
-
 // EOF
index be6e76a..ecc3915 100644 (file)
@@ -240,7 +240,13 @@ static inline Solvable *pool_id2solvable(Pool *pool, Id p)
 extern const char *solvable2str(Pool *pool, Solvable *s);
 
 void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
+
+unsigned int solvable_lookup_num(Solvable *s, Id keyname, unsigned int notfound);
+const char *solvable_lookup_str(Solvable *s, Id keyname);
 const char *solvable_lookup_str_lang(Solvable *s, Id keyname);
+int solvable_lookup_bool(Solvable *s, Id keyname);
+char * solvable_get_location(Solvable *s, unsigned int *medianrp);
+
 
 
 /**
index 2723465..361097b 100644 (file)
@@ -476,6 +476,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned
   data = repo->repodata + repo->nrepodata++;
   memset(data, 0, sizeof(*data));
   data->repo = repo;
+  data->pagefd = -1;
   data->state = REPODATA_STUB;
   data->loadcallback = repodata_load_solv;
 
@@ -526,7 +527,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned
          else
            {
              char buf[1024];
-             unsigned len = sizeof (buf);
+             unsigned len = sizeof(buf);
              char *filename = buf;
              read_str(maindata, &filename, &len);
              data->location = strdup(filename);
index 558a083..333d6bb 100644 (file)
@@ -65,6 +65,8 @@ repodata_free(Repodata *data)
   sat_free(data->attrdata);
   sat_free(data->attriddata);
   
+  sat_free(data->location);
+
   if (data->pagefd != -1)
     close(data->pagefd);
 }
@@ -373,7 +375,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
 }
 
 int
-repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
+repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value)
 {
   Id schema;
   Repokey *key;
@@ -408,6 +410,22 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
   return 0;
 }
 
+int
+repodata_lookup_void(Repodata *data, Id entry, Id keyid)
+{
+  Id schema;
+  Id *keyp;
+  unsigned char *dp;
+  if (!maybe_load_repodata(data, &keyid))
+    return 0;
+  dp = data->incoredata + data->incoreoffset[entry];
+  dp = data_read_id(dp, &schema);
+  for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
+    if (!*keyp)
+      return 0;
+  return 1;
+}
+
 void
 repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
 {
index cb81793..8bf79e6 100644 (file)
@@ -118,6 +118,7 @@ const char *repodata_lookup_str(Repodata *data, Id entry, Id keyid);
  * lookup integer type attribute
  */
 int repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value);
+int repodata_lookup_void(Repodata *data, Id entry, Id keyid);
 
 void repodata_init(Repodata *data, struct _Repo *repo, int localpool);
 void repodata_extend(Repodata *data, Id p);
diff --git a/src/solvable.c b/src/solvable.c
new file mode 100644 (file)
index 0000000..77fb427
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2008, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/*
+ * solvable.c
+ * 
+ * set/retrieve data from solvables
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "pool.h"
+#include "repo.h"
+#include "util.h"
+
+const char *
+solvable_lookup_str(Solvable *s, Id keyname)
+{
+  Repo *repo = s->repo;
+  Pool *pool;
+  Repodata *data;
+  int i, j, n;
+  const char *str;
+
+  if (!repo)
+    return 0;
+  pool = repo->pool;
+  switch(keyname)
+    {   
+    case SOLVABLE_NAME:
+      return id2str(pool, s->name);
+    case SOLVABLE_ARCH:
+      return id2str(pool, s->arch);
+    case SOLVABLE_EVR:
+      return id2str(pool, s->evr);
+    case SOLVABLE_VENDOR:
+      return id2str(pool, s->vendor);
+    }   
+  n = s - pool->solvables;
+  for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+    {   
+      if (n < data->start || n >= data->end)
+        continue;
+      for (j = 1; j < data->nkeys; j++)
+        {
+          if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID || data->keys[j].type == REPOKEY_TYPE_STR))
+           {
+              str = repodata_lookup_str(data, n - data->start, j); 
+             if (str)
+               return str;
+           }
+        }
+    }
+  return 0;
+}
+
+const char *
+solvable_lookup_str_lang(Solvable *s, Id keyname)
+{
+  Pool *pool;
+  int i, cols;
+  const char *str;
+  Id *row;
+
+  if (!s->repo)
+    return repo_lookup_str(s, keyname);
+  pool = s->repo->pool;
+  if (!pool->nlanguages)
+    return repo_lookup_str(s, keyname);
+  cols = pool->nlanguages + 1;
+  if (!pool->languagecache)
+    {
+      pool->languagecache = sat_calloc(cols * ID_NUM_INTERNAL, sizeof(Id));
+      pool->languagecacheother = 0;
+    }
+  if (keyname >= ID_NUM_INTERNAL)
+    {
+      row = pool->languagecache + ID_NUM_INTERNAL * cols;
+      for (i = 0; i < pool->languagecacheother; i++, row += cols)
+       if (*row == keyname)
+         break;
+      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++);
+       }
+    }
+  else
+    row = pool->languagecache + keyname * cols;
+  row++;       /* skip keyname */
+  for (i = 0; i < pool->nlanguages; i++, row++)
+    {
+      if (!*row)
+       {
+         char *p;
+         const char *kn;
+
+         kn = id2str(pool, keyname);
+          p = sat_malloc(strlen(kn) + strlen(pool->languages[i]) + 2);
+         sprintf(p, "%s:%s", kn, pool->languages[i]);
+         *row = str2id(pool, p, 1);
+          sat_free(p);
+       }
+      str = repo_lookup_str(s, *row);
+      if (str)
+       return str;
+    }
+  return repo_lookup_str(s, keyname);
+}
+
+unsigned int
+solvable_lookup_num(Solvable *s, Id keyname, unsigned int notfound)
+{
+  Repo *repo = s->repo;
+  Pool *pool;
+  Repodata *data;
+  int i, j, n;
+
+  if (!repo)
+    return 0;
+  pool = repo->pool;
+  if (keyname == RPM_RPMDBID)
+    {
+      if (repo->rpmdbid)
+        return repo->rpmdbid[(s - pool->solvables) - repo->start];
+      return notfound;
+    }
+  n = s - pool->solvables;
+  for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+    {
+      if (n < data->start || n >= data->end)
+        continue;
+      for (j = 1; j < data->nkeys; j++)
+        {
+          if (data->keys[j].name == keyname
+              && (data->keys[j].type == REPOKEY_TYPE_U32
+                  || data->keys[j].type == REPOKEY_TYPE_NUM
+                  || data->keys[j].type == REPOKEY_TYPE_CONSTANT))
+            {
+              unsigned int value;
+              if (repodata_lookup_num(data, n - data->start, j, &value))
+                return value;
+            }
+        }
+    }
+  return notfound;
+}
+
+int
+solvable_lookup_void(Solvable *s, Id keyname)
+{
+  Repo *repo = s->repo;
+  Pool *pool;
+  Repodata *data;
+  int i, j, n;
+
+  if (!repo)
+    return 0;
+  pool = repo->pool;
+  n = s - pool->solvables;
+  for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+    {
+      if (n < data->start || n >= data->end)
+        continue;
+      for (j = 1; j < data->nkeys; j++)
+        {
+          if (data->keys[j].name == keyname
+              && (data->keys[j].type == REPOKEY_TYPE_VOID))
+            {
+              if (repodata_lookup_void(data, n - data->start, j))
+                return 1;
+            }
+        }
+    }
+  return 0;
+}
+
+char *
+solvable_get_location(Solvable *s, unsigned int *medianrp)
+{
+  Pool *pool;
+  int l = 0;
+  char *loc;
+  const char *mediadir, *mediafile;
+
+  *medianrp = 0;
+  if (!s->repo)
+    return 0;
+  pool = s->repo->pool;
+  *medianrp = solvable_lookup_num(s, SOLVABLE_MEDIANR, 1);
+  if (solvable_lookup_void(s, SOLVABLE_MEDIADIR))
+    mediadir = id2str(pool, s->arch);
+  else
+    mediadir = solvable_lookup_str(s, SOLVABLE_MEDIADIR);
+  if (mediadir)
+    l = strlen(mediadir) + 1;
+  if (solvable_lookup_void(s, SOLVABLE_MEDIAFILE))
+    {
+      const char *name, *evr, *arch;
+      name = id2str(pool, s->name);
+      evr = id2str(pool, s->evr);
+      arch = id2str(pool, s->arch);
+      /* name-evr.arch.rpm */
+      loc = sat_malloc(l + strlen(name) + strlen(evr) + strlen(arch) + 7);
+      if (mediadir)
+       sprintf(loc, "%s/%s-%s.%s.rpm", mediadir, name, evr, arch);
+      else
+       sprintf(loc, "%s-%s.%s.rpm", name, evr, arch);
+    }
+  else
+    {
+      mediafile = solvable_lookup_str(s, SOLVABLE_MEDIAFILE);
+      if (!mediafile)
+       return 0;
+      loc = sat_malloc(l + strlen(mediafile) + 1);
+      if (mediadir)
+       sprintf(loc, "%s/%s", mediadir, mediafile);
+      else
+       strcpy(loc, mediafile);
+    }
+  return loc;
+}