2 * Copyright (c) 2013, SUSE Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
19 #include "repo_autopattern.h"
27 if (*p == '%' && p[1] && p[2])
29 int d1 = p[1], d2 = p[2];
30 if (d1 >= '0' && d1 <= '9')
32 else if (d1 >= 'a' && d1 <= 'f')
34 else if (d1 >= 'A' && d1 <= 'F')
38 if (d2 >= '0' && d2 <= '9')
40 else if (d2 >= 'a' && d2 <= 'f')
42 else if (d2 >= 'A' && d2 <= 'F')
46 if (d1 != -1 && d2 != -1)
59 repo_add_autopattern(Repo *repo, int flags)
61 Pool *pool = repo->pool;
67 Id pattern_id, product_id;
68 Id autopattern_id = 0, autoproduct_id = 0;
76 pattern_id = pool_str2id(pool, "pattern()", 9);
77 product_id = pool_str2id(pool, "product()", 9);
78 FOR_REPO_SOLVABLES(repo, p, s)
80 const char *n = pool_id2str(pool, s->name);
83 if (!strncmp("pattern:", n, 8))
88 else if (!strncmp("product:", n, 8))
96 Id prv, *prvp = repo->idarraydata + s->provides;
97 while ((prv = *prvp++) != 0) /* go through all provides */
100 Reldep *rd = GETRELDEP(pool, prv);
101 if (rd->flags != REL_EQ)
103 if (rd->name == pattern_id)
105 queue_push2(&patq2, p, rd->evr);
108 if (rd->name == product_id)
110 queue_push2(&prdq2, p, rd->evr);
116 for (i = 0; i < patq2.count; i += 2)
122 unsigned long long num;
124 s = pool->solvables + patq2.elements[i];
125 /* construct new name */
126 newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, patq2.elements[i + 1]), 0);
128 name = pool_str2id(pool, newname, 0);
131 /* check if we already have that pattern */
132 for (j = 0; j < patq.count; j++)
134 s2 = pool->solvables + patq.elements[j];
135 if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr)
139 continue; /* yes, do not add again */
143 name = pool_str2id(pool, newname, 1);
146 repo_internalize(repo); /* to make that the lookups work */
147 data = repo_add_repodata(repo, flags);
149 s2 = pool_id2solvable(pool, repo_add_solvable(repo));
150 s = pool->solvables + patq2.elements[i]; /* re-calc pointer */
154 s2->vendor = s->vendor;
155 /* add link requires */
156 s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0);
157 /* add autopattern provides */
159 autopattern_id = pool_str2id(pool, "autopattern()", 1);
160 s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0);
161 /* add self provides */
162 s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
163 if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
164 repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num);
165 if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
166 repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
167 if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
168 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
169 if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
170 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
171 /* fill in stuff from provides */
172 prvp = repo->idarraydata + s->provides;
173 while ((prv = *prvp++) != 0) /* go through all provides */
178 Reldep *rd = GETRELDEP(pool, prv);
179 if (rd->flags != REL_EQ)
184 pn = pool_id2str(pool, prv);
185 if (strncmp("pattern-", pn, 8) != 0)
190 newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
193 if (!strncmp(pn, "pattern-category(", 17) && evr)
198 if (l > 17 + 9 || pn[l - 1] != ')')
200 strncpy(lang, pn + 17, l - 17 - 1);
201 lang[l - 17 - 1] = 0;
202 langtag = SOLVABLE_CATEGORY;
203 if (*lang && strcmp(lang, "en") != 0)
204 langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1);
205 if (newname[solv_validutf8(newname)] == 0)
206 repodata_set_str(data, s2 - pool->solvables, langtag, newname);
209 char *ustr = solv_latin1toutf8(newname);
210 repodata_set_str(data, s2 - pool->solvables, langtag, ustr);
214 else if (!strcmp(pn, "pattern-includes()") && evr)
215 repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0));
216 else if (!strcmp(pn, "pattern-extends()") && evr)
217 repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0));
218 else if (!strcmp(pn, "pattern-icon()") && evr)
219 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname);
220 else if (!strcmp(pn, "pattern-order()") && evr)
221 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname);
222 else if (!strcmp(pn, "pattern-visible()") && !evr)
223 repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE);
229 if (repo == pool->installed)
230 queue_empty(&prdq2); /* no auto products for installed repos */
232 for (i = 0; i < prdq2.count; i += 2)
236 Id name, evr = 0, prv, *prvp;
238 unsigned long long num;
240 s = pool->solvables + prdq2.elements[i];
241 /* construct new name */
242 newname = pool_tmpjoin(pool, "product(", pool_id2str(pool, prdq2.elements[i + 1]), ")");
244 name = pool_str2id(pool, newname, 0);
246 continue; /* must have it in provides! */
247 prvp = repo->idarraydata + s->provides;
248 while ((prv = *prvp++) != 0) /* go through all provides */
252 Reldep *rd = GETRELDEP(pool, prv);
253 if (rd->name == name && rd->flags == REL_EQ)
261 continue; /* not found in provides */
262 newname = pool_tmpjoin(pool, "product:", pool_id2str(pool, prdq2.elements[i + 1]), 0);
264 name = pool_str2id(pool, newname, 0);
267 /* check if we already have that product */
268 for (j = 0; j < prdq.count; j++)
270 s2 = pool->solvables + prdq.elements[j];
271 if (s2->name == name && s2->arch == s->arch && s2->evr == evr)
275 continue; /* yes, do not add again */
279 name = pool_str2id(pool, newname, 1);
282 repo_internalize(repo); /* to make that the lookups work */
283 data = repo_add_repodata(repo, flags);
285 if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
286 continue; /* eek, not for installed packages, please! */
287 s2 = pool_id2solvable(pool, repo_add_solvable(repo));
288 s = pool->solvables + prdq2.elements[i]; /* re-calc pointer */
292 s2->vendor = s->vendor;
293 /* add link requires */
294 s2->requires = repo_addid_dep(repo, s2->requires, prv, 0);
296 autoproduct_id = pool_str2id(pool, "autoproduct()", 1);
297 s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autoproduct_id, s->name, REL_EQ, 1), 0);
298 /* add self provides */
299 s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
300 if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
301 repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
302 if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
303 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
304 if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
305 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
306 if ((str = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION)) != 0)
307 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DISTRIBUTION, str);
308 /* fill in stuff from provides */
309 prvp = repo->idarraydata + s->provides;
310 while ((prv = *prvp++) != 0) /* go through all provides */
315 Reldep *rd = GETRELDEP(pool, prv);
316 if (rd->flags != REL_EQ)
321 pn = pool_id2str(pool, prv);
322 if (strncmp("product-", pn, 8) != 0)
327 newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
330 if (!strcmp(pn, "product-label()") && evr)
331 repodata_set_str(data, s2 - pool->solvables, PRODUCT_SHORTLABEL, newname);
332 else if (!strcmp(pn, "product-type()") && evr)
333 repodata_set_str(data, s2 - pool->solvables, PRODUCT_TYPE, newname);
334 else if (!strcmp(pn, "product-cpeid()") && evr)
335 repodata_set_str(data, s2 - pool->solvables, SOLVABLE_CPEID, newname);
336 else if (!strcmp(pn, "product-flags()") && evr)
337 repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_FLAGS, newname);
338 else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32)
341 strcpy(type, pn + 12);
342 type[strlen(type) - 1] = 0; /* closing ) */
343 repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL_TYPE, type);
344 repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL, newname);
351 if (data && !(flags & REPO_NO_INTERNALIZE))
352 repodata_internalize(data);
353 else if (!data && !(flags & REPO_NO_INTERNALIZE))
354 repo_internalize(repo);