4 * Manage metadata coming from one repository
14 #include "poolid_private.h"
17 #define IDARRAY_BLOCK 4095
26 pool_addrepo_empty(Pool *pool)
30 pool_freewhatprovides(pool);
31 repo = (Repo *)xcalloc(1, sizeof(*repo));
32 pool->repos = (Repo **)xrealloc(pool->repos, (pool->nrepos + 1) * sizeof(Repo *));
33 pool->repos[pool->nrepos++] = repo;
36 repo->start = pool->nsolvables;
43 * olddeps = old array to extend
48 repo_addid(Repo *repo, Offset olddeps, Id id)
54 idarray = repo->idarraydata;
55 idarraysize = repo->idarraysize;
57 if (!idarray) /* alloc idarray if not done yet */
59 idarray = (Id *)xmalloc((1 + IDARRAY_BLOCK) * sizeof(Id));
65 if (!olddeps) /* no deps yet */
67 olddeps = idarraysize;
68 if ((idarraysize & IDARRAY_BLOCK) == 0)
69 idarray = (Id *)xrealloc(idarray, (idarraysize + 1 + IDARRAY_BLOCK) * sizeof(Id));
71 else if (olddeps == repo->lastoff) /* extend at end */
73 else /* can't extend, copy old */
76 olddeps = idarraysize;
77 for (; idarray[i]; i++)
79 if ((idarraysize & IDARRAY_BLOCK) == 0)
80 idarray = (Id *)xrealloc(idarray, (idarraysize + 1 + IDARRAY_BLOCK) * sizeof(Id));
81 idarray[idarraysize++] = idarray[i];
83 if ((idarraysize & IDARRAY_BLOCK) == 0)
84 idarray = (Id *)xrealloc(idarray, (idarraysize + 1 + IDARRAY_BLOCK) * sizeof(Id));
87 idarray[idarraysize++] = id; /* insert Id into array */
89 if ((idarraysize & IDARRAY_BLOCK) == 0) /* realloc if at block boundary */
90 idarray = (Id *)xrealloc(idarray, (idarraysize + 1 + IDARRAY_BLOCK) * sizeof(Id));
92 idarray[idarraysize++] = 0; /* ensure NULL termination */
94 repo->idarraydata = idarray;
95 repo->idarraysize = idarraysize;
96 repo->lastoff = olddeps;
103 * add dependency (as Id) to repo
104 * olddeps = offset into idarraydata
105 * isreq = 0 for normal dep
106 * isreq = 1 for requires
107 * isreq = 2 for pre-requires
112 repo_addid_dep(Repo *repo, Offset olddeps, Id id, int isreq)
114 Id oid, *oidp, *marker = 0;
117 return repo_addid(repo, olddeps, id);
121 for (oidp = repo->idarraydata + olddeps; (oid = *oidp) != ID_NULL; oidp++)
126 return repo_addid(repo, olddeps, id);
129 for (oidp = repo->idarraydata + olddeps; (oid = *oidp) != ID_NULL; oidp++)
131 if (oid == SOLVABLE_PREREQMARKER)
139 if (marker || isreq == 1)
142 for (; (oid = *oidp) != ID_NULL; oidp++)
143 if (oid == SOLVABLE_PREREQMARKER)
149 memmove(marker, marker + 1, (oidp - marker) * sizeof(Id));
150 *oidp = SOLVABLE_PREREQMARKER;
151 return repo_addid(repo, olddeps, id);
155 memmove(marker, marker + 1, (oidp - marker) * sizeof(Id));
159 if (isreq == 2 && !marker)
160 olddeps = repo_addid(repo, olddeps, SOLVABLE_PREREQMARKER);
161 else if (isreq == 1 && marker)
166 memmove(marker + 1, marker, (oidp - marker) * sizeof(Id));
167 *marker = SOLVABLE_PREREQMARKER;
169 return repo_addid(repo, olddeps, id);
175 * make space for 'num' more dependencies
179 repo_reserve_ids(Repo *repo, Offset olddeps, int num)
181 num++; /* room for trailing ID_NULL */
183 if (!repo->idarraysize) /* ensure buffer space */
185 repo->idarraysize = 1;
186 repo->idarraydata = (Id *)xmalloc(((1 + num + IDARRAY_BLOCK) & ~IDARRAY_BLOCK) * sizeof(Id));
187 repo->idarraydata[0] = 0;
192 if (olddeps && olddeps != repo->lastoff) /* if not appending */
194 /* can't insert into idarray, this would invalidate all 'larger' offsets
195 * so create new space at end and move existing deps there.
196 * Leaving 'hole' at old position.
202 for (idstart = idend = repo->idarraydata + olddeps; *idend++; ) /* find end */
204 count = idend - idstart - 1 + num; /* new size */
206 /* realloc if crossing block boundary */
207 if (((repo->idarraysize - 1) | IDARRAY_BLOCK) != ((repo->idarraysize + count - 1) | IDARRAY_BLOCK))
208 repo->idarraydata = (Id *)xrealloc(repo->idarraydata, ((repo->idarraysize + count + IDARRAY_BLOCK) & ~IDARRAY_BLOCK) * sizeof(Id));
210 /* move old deps to end */
211 olddeps = repo->lastoff = repo->idarraysize;
212 memcpy(repo->idarraydata + olddeps, idstart, count - num);
213 repo->idarraysize = olddeps + count - num;
218 if (olddeps) /* appending */
221 /* realloc if crossing block boundary */
222 if (((repo->idarraysize - 1) | IDARRAY_BLOCK) != ((repo->idarraysize + num - 1) | IDARRAY_BLOCK))
223 repo->idarraydata = (Id *)xrealloc(repo->idarraydata, ((repo->idarraysize + num + IDARRAY_BLOCK) & ~IDARRAY_BLOCK) * sizeof(Id));
225 /* appending or new */
226 repo->lastoff = olddeps ? olddeps : repo->idarraysize;
228 return repo->lastoff;
233 * remove repo from pool
238 pool_freerepo(Pool *pool, Repo *repo)
242 pool_freewhatprovides(pool);
244 for (i = 0; i < pool->nrepos; i++) /* find repo in pool */
246 if (pool->repos[i] == repo)
249 if (i == pool->nrepos) /* repo not in pool, return */
253 * all repos point into pool->solvables _relatively_ to repo->start
254 * so closing the gap only needs adaption of repo->start for all
258 nsolvables = repo->nsolvables;
259 if (pool->nsolvables > repo->start + nsolvables)
260 memmove(pool->solvables + repo->start, pool->solvables + repo->start + nsolvables, (pool->nsolvables - repo->start - nsolvables) * sizeof(Solvable));
261 pool->nsolvables -= nsolvables;
263 for (; i < pool->nrepos - 1; i++)
265 pool->repos[i] = pool->repos[i + 1]; /* remove repo */
266 pool->repos[i]->start -= nsolvables; /* adapt start offset of remaining repos */
270 xfree(repo->idarraydata);
271 xfree(repo->rpmdbid);
276 repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
278 Pool *pool = repo->pool;
279 Id id, idp, idl, idns;
280 char buf[1024], *p, *dep;
285 for (i = provides; repo->idarraydata[i]; i++)
287 id = repo->idarraydata[i];
290 dep = (char *)id2str(pool, id);
291 if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
294 strcpy(buf + 2, dep);
296 if ((p = strchr(dep, ':')) != 0 && p != dep)
299 idp = str2id(pool, dep, 1);
303 while ((p = strchr(dep, ';')) != 0)
310 strncpy(dep - 9, "language:", 9);
312 idl = str2id(pool, dep - 9, 1);
314 id = rel2id(pool, id, idl, REL_OR, 1);
319 if (dep[0] && dep[1])
321 for (p = dep; *p && *p != ')'; p++)
324 strncpy(dep - 9, "language:", 9);
325 idl = str2id(pool, dep - 9, 1);
327 id = rel2id(pool, id, idl, REL_OR, 1);
332 id = rel2id(pool, idp, id, REL_AND, 1);
334 supplements = repo_addid_dep(repo, supplements, id, 0);
336 else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
341 idp = str2id(pool, buf, 1);
342 idns = str2id(pool, "namespace:installed", 1);
343 id = str2id(pool, p, 1);
344 id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
345 id = rel2id(pool, idp, id, REL_AND, 1);
346 supplements = repo_addid_dep(repo, supplements, id, 0);
352 for (i = supplements; repo->idarraydata[i]; i++)
354 id = repo->idarraydata[i];
357 dep = (char *)id2str(pool, id);
358 if (!strncmp(dep, "system:modalias(", 16))
360 if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
363 p = strchr(buf + 9, ':');
364 idns = str2id(pool, "namespace:modalias", 1);
365 if (p && p != buf + 9 && strchr(p + 1, ':'))
368 idp = str2id(pool, buf + 9, 1);
369 p[strlen(p) - 1] = 0;
370 id = str2id(pool, p, 1);
371 id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
372 id = rel2id(pool, idp, id, REL_AND, 1);
377 p[strlen(p) - 1] = 0;
378 id = str2id(pool, p, 1);
379 id = rel2id(pool, idns, id, REL_NAMESPACE, 1);
382 repo->idarraydata[i] = id;
384 else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
389 while ((p = strchr(dep, ':')) != 0)
397 idp = str2id(pool, dep, 1);
399 id = rel2id(pool, id, idp, REL_AND, 1);
404 if (dep[0] && dep[1])
406 dep[strlen(dep) - 1] = 0;
407 idp = str2id(pool, dep, 1);
409 id = rel2id(pool, id, idp, REL_AND, 1);
414 repo->idarraydata[i] = id;