2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
11 * Manage metadata coming from one repository
26 #include "poolid_private.h"
29 #include "attr_store_p.h"
32 #define IDARRAY_BLOCK 4095
41 repo_create(Pool *pool, const char *name)
45 pool_freewhatprovides(pool);
46 repo = (Repo *)sat_calloc(1, sizeof(*repo));
47 pool->repos = (Repo **)sat_realloc2(pool->repos, pool->nrepos + 1, sizeof(Repo *));
48 pool->repos[pool->nrepos++] = repo;
49 repo->repoid = pool->nrepos;
50 repo->name = name ? strdup(name) : 0;
52 repo->start = pool->nsolvables;
53 repo->end = pool->nsolvables;
59 repo_freedata(Repo *repo)
62 for (i = 0; i < repo->nrepodata; i++)
63 repodata_free(repo->repodata + i);
64 sat_free(repo->repodata);
65 sat_free(repo->idarraydata);
66 sat_free(repo->rpmdbid);
67 sat_free((char *)repo->name);
73 * olddeps = old array to extend
78 repo_addid(Repo *repo, Offset olddeps, Id id)
84 idarray = repo->idarraydata;
85 idarraysize = repo->idarraysize;
87 if (!idarray) /* alloc idarray if not done yet */
90 idarray = sat_extend_resize(0, 1, sizeof(Id), IDARRAY_BLOCK);
95 if (!olddeps) /* no deps yet */
97 olddeps = idarraysize;
98 idarray = sat_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
100 else if (olddeps == repo->lastoff) /* extend at end */
102 else /* can't extend, copy old */
105 olddeps = idarraysize;
106 for (; idarray[i]; i++)
108 idarray = sat_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
109 idarray[idarraysize++] = idarray[i];
111 idarray = sat_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
114 idarray[idarraysize++] = id; /* insert Id into array */
115 idarray = sat_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
116 idarray[idarraysize++] = 0; /* ensure NULL termination */
118 repo->idarraydata = idarray;
119 repo->idarraysize = idarraysize;
120 repo->lastoff = olddeps;
127 * add dependency (as Id) to repo, also unifies dependencies
128 * olddeps = offset into idarraydata
129 * marker= 0 for normal dep
130 * marker > 0 add dep after marker
131 * marker < 0 add dep after -marker
135 repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker)
137 Id oid, *oidp, *markerp;
143 olddeps = repo_addid(repo, olddeps, marker);
144 return repo_addid(repo, olddeps, id);
149 for (oidp = repo->idarraydata + olddeps; (oid = *oidp) != ID_NULL; oidp++)
154 return repo_addid(repo, olddeps, id);
164 for (oidp = repo->idarraydata + olddeps; (oid = *oidp) != ID_NULL; oidp++)
174 if (markerp || before)
176 /* we found it, but in the wrong half */
178 for (; (oid = *oidp) != ID_NULL; oidp++)
183 /* no marker in array yet */
186 memmove(markerp, markerp + 1, (oidp - markerp) * sizeof(Id));
188 return repo_addid(repo, olddeps, id);
192 memmove(markerp, markerp + 1, (oidp - markerp) * sizeof(Id));
196 /* id not yet in array */
197 if (!before && !markerp)
198 olddeps = repo_addid(repo, olddeps, marker);
199 else if (before && markerp)
204 memmove(markerp + 1, markerp, (oidp - markerp) * sizeof(Id));
207 return repo_addid(repo, olddeps, id);
213 * make space for 'num' more dependencies
217 repo_reserve_ids(Repo *repo, Offset olddeps, int num)
219 num++; /* room for trailing ID_NULL */
221 if (!repo->idarraysize) /* ensure buffer space */
223 repo->idarraysize = 1;
224 repo->idarraydata = sat_extend_resize(0, 1 + num, sizeof(Id), IDARRAY_BLOCK);
225 repo->idarraydata[0] = 0;
230 if (olddeps && olddeps != repo->lastoff) /* if not appending */
232 /* can't insert into idarray, this would invalidate all 'larger' offsets
233 * so create new space at end and move existing deps there.
234 * Leaving 'hole' at old position.
240 for (idstart = idend = repo->idarraydata + olddeps; *idend++; ) /* find end */
242 count = idend - idstart - 1 + num; /* new size */
244 repo->idarraydata = sat_extend(repo->idarraydata, repo->idarraysize, count, sizeof(Id), IDARRAY_BLOCK);
245 /* move old deps to end */
246 olddeps = repo->lastoff = repo->idarraysize;
247 memcpy(repo->idarraydata + olddeps, idstart, count - num);
248 repo->idarraysize = olddeps + count - num;
253 if (olddeps) /* appending */
257 repo->idarraydata = sat_extend(repo->idarraydata, repo->idarraysize, num, sizeof(Id), IDARRAY_BLOCK);
259 /* appending or new */
260 repo->lastoff = olddeps ? olddeps : repo->idarraysize;
262 return repo->lastoff;
267 * remove repo from pool, zero out solvables
272 repo_free(Repo *repo, int reuseids)
274 Pool *pool = repo->pool;
278 pool_freewhatprovides(pool);
279 if (repo == pool->installed)
282 if (reuseids && repo->end == pool->nsolvables)
284 /* it's ok to reuse the ids. As this is the last repo, we can
285 just shrink the solvable array */
286 for (i = repo->end - 1, s = pool->solvables + i; i >= repo->start; i--, s--)
290 pool->nsolvables = i + 1;
292 /* zero out solvables belonging to this repo */
293 for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++)
295 memset(s, 0, sizeof(*s));
296 for (i = 0; i < pool->nrepos; i++) /* find repo in pool */
297 if (pool->repos[i] == repo)
299 if (i == pool->nrepos) /* repo not in pool, return */
301 if (i < pool->nrepos - 1)
303 memmove(pool->repos + i, pool->repos + i + 1, (pool->nrepos - 1 - i) * sizeof(Repo *));
305 for (; i < pool->nrepos - 1; i++)
306 pool->repos[i]->repoid = i + 1;
313 repo_freeallrepos(Pool *pool, int reuseids)
317 pool_freewhatprovides(pool);
318 for (i = 0; i < pool->nrepos; i++)
319 repo_freedata(pool->repos[i]);
320 pool->repos = sat_free(pool->repos);
322 /* the first two solvables don't belong to a repo */
323 pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids);
327 #define REPO_SIDEDATA_BLOCK 63
330 repo_sidedata_create(Repo *repo, size_t size)
332 return sat_calloc_block(repo->end - repo->start, size, REPO_SIDEDATA_BLOCK);
336 repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count)
338 int n = repo->end - repo->start;
341 int d = repo->start - p;
342 b = sat_extend(b, n, d, size, REPO_SIDEDATA_BLOCK);
343 memmove((char*)b + d * size, b, n * size);
344 memset(b, 0, d * size);
347 if (p + count > repo->end)
349 int d = p + count - repo->end;
350 b = sat_extend(b, n, d, size, REPO_SIDEDATA_BLOCK);
351 memset((char*)b + n * size, 0, d * size);
357 repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
359 Pool *pool = repo->pool;
361 char buf[1024], *p, *dep;
366 for (i = provides; repo->idarraydata[i]; i++)
368 id = repo->idarraydata[i];
371 dep = (char *)id2str(pool, id);
372 if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
375 strcpy(buf + 2, dep);
377 if ((p = strchr(dep, ':')) != 0 && p != dep)
380 idp = str2id(pool, dep, 1);
384 while ((p = strchr(dep, ';')) != 0)
393 strncpy(dep - 9, "language:", 9);
394 idl = str2id(pool, dep - 9, 1);
396 idl = str2id(pool, dep, 1);
397 idl = rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
400 id = rel2id(pool, id, idl, REL_OR, 1);
405 if (dep[0] && dep[1])
407 for (p = dep; *p && *p != ')'; p++)
411 strncpy(dep - 9, "language:", 9);
412 idl = str2id(pool, dep - 9, 1);
414 idl = str2id(pool, dep, 1);
415 idl = rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
418 id = rel2id(pool, id, idl, REL_OR, 1);
423 id = rel2id(pool, idp, id, REL_AND, 1);
425 supplements = repo_addid_dep(repo, supplements, id, 0);
427 else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
432 idp = str2id(pool, buf, 1);
433 /* strip trailing slashes */
435 while (l > 1 && p[l - 1] == '/')
437 id = str2id(pool, p, 1);
438 id = rel2id(pool, idp, id, REL_WITH, 1);
439 id = rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
440 supplements = repo_addid_dep(repo, supplements, id, 0);
446 for (i = supplements; repo->idarraydata[i]; i++)
448 id = repo->idarraydata[i];
451 dep = (char *)id2str(pool, id);
452 if (!strncmp(dep, "system:modalias(", 16))
454 if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
457 p = strchr(buf + 9, ':');
458 if (p && p != buf + 9 && strchr(p + 1, ':'))
461 idp = str2id(pool, buf + 9, 1);
462 p[strlen(p) - 1] = 0;
463 id = str2id(pool, p, 1);
464 id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
465 id = rel2id(pool, idp, id, REL_AND, 1);
470 p[strlen(p) - 1] = 0;
471 id = str2id(pool, p, 1);
472 id = rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
475 repo->idarraydata[i] = id;
477 else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
482 while ((p = strchr(dep, ':')) != 0)
490 idp = str2id(pool, dep, 1);
492 id = rel2id(pool, id, idp, REL_AND, 1);
497 if (dep[0] && dep[1])
499 dep[strlen(dep) - 1] = 0;
500 idp = str2id(pool, dep, 1);
502 id = rel2id(pool, id, idp, REL_AND, 1);
507 repo->idarraydata[i] = id;
509 else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
511 strcpy(buf, dep + 11);
512 if ((p = strrchr(buf, ')')) != 0)
514 id = str2id(pool, buf, 1);
515 id = rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
516 repo->idarraydata[i] = id;
520 if (freshens && repo->idarraydata[freshens])
522 Id idsupp = 0, idfresh = 0;
525 for (i = supplements; repo->idarraydata[i]; i++)
528 idsupp = repo->idarraydata[i];
530 idsupp = rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
532 for (i = freshens; repo->idarraydata[i]; i++)
535 idfresh = repo->idarraydata[i];
537 idfresh = rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
542 idsupp = rel2id(pool, idsupp, idfresh, REL_AND, 1);
543 supplements = repo_addid_dep(repo, 0, idsupp, 0);
549 repo_fix_conflicts(Repo *repo, Offset conflicts)
551 char buf[1024], *p, *dep;
552 Pool *pool = repo->pool;
558 for (i = conflicts; repo->idarraydata[i]; i++)
560 id = repo->idarraydata[i];
563 dep = (char *)id2str(pool, id);
564 if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
566 strcpy(buf, dep + 15);
567 if ((p = strchr(buf, ')')) != 0)
569 id = str2id(pool, buf, 1);
570 id = rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
571 repo->idarraydata[i] = id;
583 int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv);
588 repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
590 struct matchdata *md = cbdata;
592 if (md->matcher.match)
594 if (!repodata_stringify(md->pool, data, key, kv, md->flags))
596 if (!datamatcher_match(&md->matcher, kv->str))
599 md->stop = md->callback(md->callback_data, s, data, key, kv);
604 static Repokey solvablekeys[RPM_RPMDBID - SOLVABLE_NAME + 1] = {
605 { SOLVABLE_NAME, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
606 { SOLVABLE_ARCH, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
607 { SOLVABLE_EVR, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
608 { SOLVABLE_VENDOR, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
609 { SOLVABLE_PROVIDES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
610 { SOLVABLE_OBSOLETES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
611 { SOLVABLE_CONFLICTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
612 { SOLVABLE_REQUIRES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
613 { SOLVABLE_RECOMMENDS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
614 { SOLVABLE_SUGGESTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
615 { SOLVABLE_SUPPLEMENTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
616 { SOLVABLE_ENHANCES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
617 { RPM_RPMDBID, REPOKEY_TYPE_U32, 0, KEY_STORAGE_SOLVABLE },
621 domatch_idarray(Solvable *s, Id keyname, struct matchdata *md, Id *ida)
626 for (; *ida && !md->stop; ida++)
629 kv.eof = ida[1] ? 0 : 1;
630 repo_matchvalue(md, s, 0, solvablekeys + (keyname - SOLVABLE_NAME), &kv);
636 repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
639 Pool *pool = repo->pool;
648 for (p = repo->start, s = repo->pool->solvables + p; p < repo->end; p++, s++)
651 repo_search_md(repo, p, keyname, md);
652 if (md->stop > SEARCH_NEXT_SOLVABLE)
658 /* The callback only supports solvables, so we can't iterate over the
662 if (!(flags & SEARCH_NO_STORAGE_SOLVABLE))
664 s = pool->solvables + p;
672 repo_matchvalue(md, s, 0, solvablekeys + 0, &kv);
674 if (keyname || md->stop > SEARCH_NEXT_KEY)
680 repo_matchvalue(md, s, 0, solvablekeys + 1, &kv);
682 if (keyname || md->stop > SEARCH_NEXT_KEY)
688 repo_matchvalue(md, s, 0, solvablekeys + 2, &kv);
690 if (keyname || md->stop > SEARCH_NEXT_KEY)
692 case SOLVABLE_VENDOR:
696 repo_matchvalue(md, s, 0, solvablekeys + 3, &kv);
698 if (keyname || md->stop > SEARCH_NEXT_KEY)
700 case SOLVABLE_PROVIDES:
702 domatch_idarray(s, SOLVABLE_PROVIDES, md, repo->idarraydata + s->provides);
703 if (keyname || md->stop > SEARCH_NEXT_KEY)
705 case SOLVABLE_OBSOLETES:
707 domatch_idarray(s, SOLVABLE_OBSOLETES, md, repo->idarraydata + s->obsoletes);
708 if (keyname || md->stop > SEARCH_NEXT_KEY)
710 case SOLVABLE_CONFLICTS:
712 domatch_idarray(s, SOLVABLE_CONFLICTS, md, repo->idarraydata + s->conflicts);
713 if (keyname || md->stop > SEARCH_NEXT_KEY)
715 case SOLVABLE_REQUIRES:
717 domatch_idarray(s, SOLVABLE_REQUIRES, md, repo->idarraydata + s->requires);
718 if (keyname || md->stop > SEARCH_NEXT_KEY)
720 case SOLVABLE_RECOMMENDS:
722 domatch_idarray(s, SOLVABLE_RECOMMENDS, md, repo->idarraydata + s->recommends);
723 if (keyname || md->stop > SEARCH_NEXT_KEY)
725 case SOLVABLE_SUPPLEMENTS:
727 domatch_idarray(s, SOLVABLE_SUPPLEMENTS, md, repo->idarraydata + s->supplements);
728 if (keyname || md->stop > SEARCH_NEXT_KEY)
730 case SOLVABLE_SUGGESTS:
732 domatch_idarray(s, SOLVABLE_SUGGESTS, md, repo->idarraydata + s->suggests);
733 if (keyname || md->stop > SEARCH_NEXT_KEY)
735 case SOLVABLE_ENHANCES:
737 domatch_idarray(s, SOLVABLE_ENHANCES, md, repo->idarraydata + s->enhances);
738 if (keyname || md->stop > SEARCH_NEXT_KEY)
743 kv.num = repo->rpmdbid[p - repo->start];
744 repo_matchvalue(md, s, 0, solvablekeys + (RPM_RPMDBID - SOLVABLE_NAME), &kv);
746 if (keyname || md->stop > SEARCH_NEXT_KEY)
754 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
756 if (p < data->start || p >= data->end)
758 if (keyname && !repodata_precheck_keyname(data, keyname))
760 if (data->state == REPODATA_STUB)
764 for (j = 1; j < data->nkeys; j++)
765 if (keyname == data->keys[j].name)
767 if (j == data->nkeys)
771 if (data->loadcallback)
772 data->loadcallback(data);
774 data->state = REPODATA_ERROR;
776 if (data->state == REPODATA_ERROR)
778 repodata_search(data, p, keyname, md->flags, repo_matchvalue, md);
779 if (md->stop > SEARCH_NEXT_KEY)
785 repo_search(Repo *repo, Id p, Id keyname, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
789 memset(&md, 0, sizeof(md));
790 md.pool = repo->pool;
792 md.callback = callback;
793 md.callback_data = cbdata;
795 datamatcher_init(&md.matcher, match, flags);
796 repo_search_md(repo, p, keyname, &md);
798 datamatcher_free(&md.matcher);
802 repo_lookup_str(Repo *repo, Id entry, Id keyname)
804 Pool *pool = repo->pool;
811 return id2str(pool, pool->solvables[entry].name);
813 return id2str(pool, pool->solvables[entry].arch);
815 return id2str(pool, pool->solvables[entry].evr);
816 case SOLVABLE_VENDOR:
817 return id2str(pool, pool->solvables[entry].vendor);
819 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
821 if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
823 if (!repodata_precheck_keyname(data, keyname))
825 for (j = 1; j < data->nkeys; j++)
827 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))
828 return repodata_lookup_str(data, entry, keyname);
836 repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned int notfound)
841 if (keyname == RPM_RPMDBID)
843 if (repo->rpmdbid && entry >= repo->start && entry < repo->end)
844 return repo->rpmdbid[entry - repo->start];
847 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
849 if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
851 if (!repodata_precheck_keyname(data, keyname))
853 for (j = 1; j < data->nkeys; j++)
855 if (data->keys[j].name == keyname
856 && (data->keys[j].type == REPOKEY_TYPE_U32
857 || data->keys[j].type == REPOKEY_TYPE_NUM
858 || data->keys[j].type == REPOKEY_TYPE_CONSTANT))
861 if (repodata_lookup_num(data, entry, keyname, &value))
870 repo_lookup_id(Repo *repo, Id entry, Id keyname)
878 return repo->pool->solvables[entry].name;
880 return repo->pool->solvables[entry].arch;
882 return repo->pool->solvables[entry].evr;
883 case SOLVABLE_VENDOR:
884 return repo->pool->solvables[entry].vendor;
886 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
888 if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
890 if (!repodata_precheck_keyname(data, keyname))
892 for (j = 1; j < data->nkeys; j++)
894 if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID))
896 Id id = repodata_lookup_id(data, entry, keyname);
900 id = repodata_globalize_id(data, id);
909 const unsigned char *
910 repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
914 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
916 if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
918 if (!repodata_precheck_keyname(data, keyname))
920 for (j = 1; j < data->nkeys; j++)
922 if (data->keys[j].name == keyname)
924 const unsigned char *chk = repodata_lookup_bin_checksum(data, entry, keyname, typep);
935 repo_lookup_void(Repo *repo, Id entry, Id keyname)
939 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
941 if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
943 if (!repodata_precheck_keyname(data, keyname))
945 for (j = 1; j < data->nkeys; j++)
947 if (data->keys[j].name == keyname
948 && (data->keys[j].type == REPOKEY_TYPE_VOID))
950 if (repodata_lookup_void(data, entry, keyname))
958 /***********************************************************************/
961 repo_add_repodata(Repo *repo, int localpool)
966 repo->repodata = sat_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
967 data = repo->repodata + repo->nrepodata - 1;
968 repodata_init(data, repo, localpool);
973 repo_last_repodata(Repo *repo)
976 for (i = repo->nrepodata - 1; i >= 0; i--)
977 if (repo->repodata[i].state != REPODATA_STUB)
978 return repo->repodata + i;
979 return repo_add_repodata(repo, 0);
983 repo_set_id(Repo *repo, Id p, Id keyname, Id id)
985 Repodata *data = repo_last_repodata(repo);
986 repodata_set_id(data, p, keyname, id);
990 repo_set_num(Repo *repo, Id p, Id keyname, Id num)
992 Repodata *data = repo_last_repodata(repo);
993 repodata_set_num(data, p, keyname, num);
997 repo_set_str(Repo *repo, Id p, Id keyname, const char *str)
999 Repodata *data = repo_last_repodata(repo);
1000 repodata_set_str(data, p, keyname, str);
1004 repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str)
1006 Repodata *data = repo_last_repodata(repo);
1007 repodata_set_poolstr(data, p, keyname, str);
1011 repo_add_poolstr_array(Repo *repo, Id p, Id keyname, const char *str)
1013 Repodata *data = repo_last_repodata(repo);
1014 repodata_add_poolstr_array(data, p, keyname, str);
1018 repo_internalize(Repo *repo)
1023 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
1024 if (data->attrs || data->xattrs)
1025 repodata_internalize(data);
1029 repo_disable_paging(Repo *repo)
1034 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
1035 repodata_disable_paging(data);
1039 vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: