4 * Parses 'content' file into .solv
5 * See http://en.opensuse.org/Standards/YaST2_Repository_Metadata/content for a description
9 * Copyright (c) 2007, Novell Inc.
11 * This program is licensed under the BSD license, read LICENSE.BSD
12 * for further information
15 #include <sys/types.h>
26 #include "repo_content.h"
29 /* split off a word, return null terminated pointer to it.
30 * return NULL if there is no word left. */
36 while (*l == ' ' || *l == '\t')
39 while (*l && *l != ' ' && *l != '\t')
42 *l++ = 0; /* terminate word */
43 while (*l == ' ' || *l == '\t')
44 l++; /* convenience: advance to next word */
57 makeevr(Pool *pool, char *s)
59 if (!strncmp(s, "0:", 2) && s[2])
61 return str2id(pool, s, 1);
65 * dependency relations
68 static char *flagtab[] = {
79 * join up to three strings into one
83 join(struct parsedata *pd, const char *s1, const char *s2, const char *s3)
97 pd->tmp = sat_realloc(pd->tmp, pd->tmpl);
120 * add dependency to pool
124 adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker)
129 while ((name = splitword(&line)) != 0)
131 /* Hack, as the content file adds 'package:' for package
132 dependencies sometimes. */
133 if (!strncmp (name, "package:", 8))
135 id = str2id(pool, name, 1);
136 if (strpbrk(line, "<>="))
138 char *rel = splitword(&line);
139 char *evr = splitword(&line);
144 fprintf(stderr, "bad relation '%s %s'\n", name, rel);
147 for (flags = 0; flags < 6; flags++)
148 if (!strcmp(rel, flagtab[flags]))
152 fprintf(stderr, "Unknown relation '%s'\n", rel);
155 id = rel2id(pool, id, str2id(pool, evr, 1), flags + 1, 1);
157 olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
164 * split value and add to pool
168 add_multiple_strings(Repodata *data, Id handle, Id name, char *value)
172 while ((str = splitword(&value)) != 0)
173 repodata_add_poolstr_array(data, handle, name, str);
177 * split value and add to pool
181 add_multiple_urls(Repodata *data, Id handle, char *value, Id type)
185 while ((url = splitword(&value)) != 0)
187 repodata_add_poolstr_array(data, handle, PRODUCT_URL, url);
188 repodata_add_idarray(data, handle, PRODUCT_URL_TYPE, type);
195 * add 'content' to repo
200 repo_add_content(Repo *repo, FILE *fp)
202 Pool *pool = repo->pool;
209 int contentstyle = 0;
214 we use the first architecture in BASEARCHS or noarch
215 for the product. At the end we create (clone) the product
216 for each one of the remaining architectures
219 unsigned int numotherarchs = 0;
222 memset(&pd, 0, sizeof(pd));
223 line = sat_malloc(1024);
227 /* use last repodata */
228 data = repo->repodata + repo->nrepodata - 1;
230 data = repo_add_repodata(repo, 0);
240 /* read line into big-enough buffer */
241 if (linep - line + 16 > aline)
243 aline = linep - line;
244 line = sat_realloc(line, aline + 512);
245 linep = line + aline;
248 if (!fgets(linep, aline - (linep - line), fp))
250 linep += strlen(linep);
251 if (linep == line || linep[-1] != '\n')
256 /* expect "key value" lines */
258 key = splitword(&value);
263 fprintf (stderr, "key %s, value %s\n", key, value);
266 #define istag(x) (!strcmp (key, x))
267 #define code10 (contentstyle == 10)
268 #define code11 (contentstyle == 11)
270 if (contentstyle == 0)
272 if (istag ("CONTENTSTYLE"))
274 contentstyle = atoi(value);
281 if ((code10 && istag ("PRODUCT"))
282 || (code11 && istag ("NAME")))
286 /* this solvable was created without seeing a
287 PRODUCT entry, just set the name and continue */
288 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
293 /* finish old solvable */
295 s->arch = ARCH_NOARCH;
296 if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
297 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
299 s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
301 /* create new solvable */
302 s = pool_id2solvable(pool, repo_add_solvable(repo));
303 repodata_extend(data, s - pool->solvables);
304 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
305 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
309 /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
313 s = pool_id2solvable(pool, repo_add_solvable(repo));
314 repodata_extend(data, s - pool->solvables);
315 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
318 if (code11 && istag ("REFERENCES"))
319 repo_set_id(repo, s - pool->solvables, PRODUCT_REFERENCES, str2id(pool, value, 1));
320 else if (istag ("VERSION"))
321 s->evr = makeevr(pool, value);
322 else if (code11 && istag ("DISTRIBUTION"))
323 repo_set_str(repo, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
324 else if (code11 && istag ("FLAVOR"))
325 repo_set_str(repo, s - pool->solvables, PRODUCT_FLAVOR, value);
326 else if (istag ("DATADIR"))
327 repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
328 else if (istag ("UPDATEURLS"))
329 add_multiple_urls(data, handle, value, str2id(pool, "update", 1));
330 else if (istag ("EXTRAURLS"))
331 add_multiple_urls(data, handle, value, str2id(pool, "extra", 1));
332 else if (istag ("OPTIONALURLS"))
333 add_multiple_urls(data, handle, value, str2id(pool, "optional", 1));
334 else if (istag ("RELNOTESURL"))
335 add_multiple_urls(data, handle, value, str2id(pool, "releasenotes", 1));
336 else if (istag ("SHORTLABEL"))
337 repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
338 else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
339 repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
340 else if (!strncmp (key, "LABEL.", 6))
341 repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
342 else if (istag ("FLAGS"))
343 add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
344 else if (istag ("VENDOR"))
345 s->vendor = str2id(pool, value, 1);
346 else if (istag ("BASEARCHS"))
350 if ((arch = splitword(&value)) != 0)
352 s->arch = str2id(pool, arch, 1);
353 while ((arch = splitword(&value)) != 0)
355 otherarchs = sat_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
356 otherarchs[numotherarchs++] = str2id(pool, arch, 1);
362 * Every tag below is Code10 only
366 else if (code10 && istag ("DISTPRODUCT"))
367 /* DISTPRODUCT is for registration and Yast, not for the solver. */
368 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
369 else if (code10 && istag ("DISTVERSION"))
370 /* DISTVERSION is for registration and Yast, not for the solver. */
371 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
372 else if (code10 && istag ("ARCH"))
373 /* Theoretically we want to have the best arch of the given
374 modifiers which still is compatible with the system
375 arch. We don't know the latter here, though. */
376 s->arch = ARCH_NOARCH;
377 else if (code10 && istag ("PREREQUIRES"))
378 s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
379 else if (code10 && istag ("REQUIRES"))
380 s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
381 else if (code10 && istag ("PROVIDES"))
382 s->provides = adddep(pool, &pd, s->provides, value, 0);
383 else if (code10 && istag ("CONFLICTS"))
384 s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
385 else if (code10 && istag ("OBSOLETES"))
386 s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
387 else if (code10 && istag ("RECOMMENDS"))
388 s->recommends = adddep(pool, &pd, s->recommends, value, 0);
389 else if (code10 && istag ("SUGGESTS"))
390 s->suggests = adddep(pool, &pd, s->suggests, value, 0);
391 else if (code10 && istag ("SUPPLEMENTS"))
392 s->supplements = adddep(pool, &pd, s->supplements, value, 0);
393 else if (code10 && istag ("ENHANCES"))
394 s->enhances = adddep(pool, &pd, s->enhances, value, 0);
395 /* FRESHENS doesn't seem to exist. */
396 else if (code10 && istag ("TYPE"))
397 repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
399 /* XXX do something about LINGUAS and ARCH?
400 * <ma>: Don't think so. zypp does not use or propagate them.
405 fprintf (stderr, "malformed line: %s\n", line);
410 fprintf(stderr, "No product solvable created !\n");
415 s->arch = ARCH_NOARCH;
416 if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
418 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
420 s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
423 /* now for every other arch, clone the product except the architecture */
424 for (i = 0; i < numotherarchs; ++i)
426 Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
427 repodata_extend(data, p - pool->solvables);
428 /*handle = repodata_get_handle(data, p - pool->solvables - repo->start);*/
431 p->vendor = s->vendor;
432 p->arch = otherarchs[i];
435 if (p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
436 p->provides = repo_addid_dep(repo, p->provides, rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);
438 /* now merge the attributes */
439 repodata_merge_attrs(data, p - pool->solvables - repo->start, s - pool->solvables- repo->start);
443 repodata_internalize(data);
448 sat_free(otherarchs);