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 l into m parts, store to sp[]
34 split(char *l, char **sp, int m)
39 while (*l == ' ' || *l == '\t')
46 while (*l && !(*l == ' ' || *l == '\t'))
64 makeevr(Pool *pool, char *s)
66 if (!strncmp(s, "0:", 2) && s[2])
68 return str2id(pool, s, 1);
72 * dependency relations
75 static char *flagtab[] = {
86 * join up to three strings into one
90 join(struct parsedata *pd, const char *s1, const char *s2, const char *s3)
104 pd->tmp = sat_realloc(pd->tmp, pd->tmpl);
127 * add dependency to pool
131 adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker)
140 /* Name [relop evr] [rest] --> 1, 2, 3 or 4 fields. */
143 words += split(line, sp + words, 4 - words);
146 /* Hack, as the content file adds 'package:' for package
147 dependencies sometimes. */
148 if (!strncmp (sp[0], "package:", 8))
150 id = str2id(pool, sp[0], 1);
151 if (words >= 3 && strpbrk (sp[1], "<>="))
153 evrid = makeevr(pool, sp[2]);
154 for (flags = 0; flags < 6; flags++)
155 if (!strcmp(sp[1], flagtab[flags]))
159 fprintf(stderr, "Unknown relation '%s'\n", sp[1]);
162 id = rel2id(pool, id, evrid, flags + 1, 1);
163 /* Consume three words, there's nothing to move to front. */
171 /* Consume one word. If we had more move them to front. */
173 for (j = 0; j < words; j++)
176 line = sp[2], words = 2;
178 olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
179 if (! ( line || words > 0 ) )
187 * split value and add to pool
191 add_multiple_strings(Repodata *data, Id handle, Id name, char *value)
196 int words = split(value, sp, 2);
199 repodata_add_poolstr_array(data, handle, name, sp[0]);
207 * split value and add to pool
211 add_multiple_urls(Repodata *data, Id handle, char *value, Id type)
216 int words = split(value, sp, 2);
219 repodata_add_poolstr_array(data, handle, PRODUCT_URL, sp[0]);
220 repodata_add_idarray(data, handle, PRODUCT_URL_TYPE, type);
230 * add 'content' to repo
235 repo_add_content(Repo *repo, FILE *fp)
237 Pool *pool = repo->pool;
240 Solvable *s, *firsts = 0;
244 int contentstyle = 0;
249 we use the first architecture in BASEARCHS or noarch
250 for the product. At the end we create (clone) the product
251 for each one of the remaining architectures
254 unsigned int numotherarchs = 0;
259 memset(&pd, 0, sizeof(pd));
260 line = sat_malloc(1024);
264 /* use last repodata */
265 data = repo->repodata + repo->nrepodata - 1;
267 data = repo_add_repodata(repo, 0);
277 /* read line into big-enough buffer */
278 if (linep - line + 16 > aline)
280 aline = linep - line;
281 line = sat_realloc(line, aline + 512);
282 linep = line + aline;
285 if (!fgets(linep, aline - (linep - line), fp))
287 linep += strlen(linep);
288 if (linep == line || linep[-1] != '\n')
293 /* expect "key value" lines */
294 if (split (line, fields, 2) == 2)
296 char *key = fields[0];
297 char *value = fields[1];
299 fprintf (stderr, "key %s, value %s\n", key, fields[1]);
302 #define istag(x) (!strcmp (key, x))
303 #define code10 (contentstyle == 10)
304 #define code11 (contentstyle == 11)
306 if (contentstyle == 0)
308 if (istag ("CONTENTSTYLE"))
310 contentstyle = atoi(value);
317 if ((code10 && istag ("PRODUCT"))
318 || (code11 && istag ("NAME")))
320 /* Finish old solvable, but only if it wasn't created
321 on demand without seeing a PRODUCT entry. */
324 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
325 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
327 s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
329 s = pool_id2solvable(pool, repo_add_solvable(repo));
330 repodata_extend(data, s - pool->solvables);
331 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
334 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
338 /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
342 firsts = s = pool_id2solvable(pool, repo_add_solvable(repo));
343 repodata_extend(data, s - pool->solvables);
344 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
347 if (code11 && istag ("REFERENCES"))
348 repo_set_id(repo, s - pool->solvables, PRODUCT_REFERENCES, str2id(pool, value, 1));
349 else if (istag ("VERSION"))
350 s->evr = makeevr(pool, value);
351 else if (code11 && istag ("DISTRIBUTION"))
352 repo_set_str(repo, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
353 else if (code11 && istag ("FLAVOR"))
354 repo_set_str(repo, s - pool->solvables, PRODUCT_FLAVOR, value);
355 else if (istag ("DATADIR"))
356 repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
357 else if (istag ("UPDATEURLS"))
358 add_multiple_urls(data, handle, value, PRODUCT_URL_TYPE_UPDATE);
359 else if (istag ("EXTRAURLS"))
360 add_multiple_urls(data, handle, value, PRODUCT_URL_TYPE_EXTRA);
361 else if (istag ("OPTIONALURLS"))
362 add_multiple_urls(data, handle, value, PRODUCT_URL_TYPE_OPTIONAL);
363 else if (istag ("RELNOTESURL"))
364 add_multiple_urls(data, handle, value, PRODUCT_URL_TYPE_RELNOTES);
365 else if (istag ("SHORTLABEL"))
366 repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
367 else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
368 repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
369 else if (!strncmp (key, "LABEL.", 6))
370 repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
371 else if (istag ("FLAGS"))
372 add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
373 else if (istag ("VENDOR"))
374 s->vendor = str2id(pool, value, 1);
375 else if (istag ("BASEARCHS"))
379 /* get the first architecture and use it
380 for the product arch */
381 int words = split(value, sp, 2);
384 /* there is at least one architecture */
385 s->arch = str2id(pool, sp[0], 1);
386 /* ignore the rest for now */
389 while ( value && (numotherarchs < 5) )
391 words = split(value, sp, 2);
394 /* we have a new extra architecture */
396 otherarchs[numotherarchs - 1 ] = str2id(pool, sp[0], 1);
405 * Every tag below is Code10 only
409 else if (code10 && istag ("DISTPRODUCT"))
410 /* DISTPRODUCT is for registration and Yast, not for the solver. */
411 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
412 else if (code10 && istag ("DISTVERSION"))
413 /* DISTVERSION is for registration and Yast, not for the solver. */
414 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
415 else if (code10 && istag ("ARCH"))
416 /* Theoretically we want to have the best arch of the given
417 modifiers which still is compatible with the system
418 arch. We don't know the latter here, though. */
419 s->arch = ARCH_NOARCH;
420 else if (code10 && istag ("PREREQUIRES"))
421 s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
422 else if (code10 && istag ("REQUIRES"))
423 s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
424 else if (code10 && istag ("PROVIDES"))
425 s->provides = adddep(pool, &pd, s->provides, value, 0);
426 else if (code10 && istag ("CONFLICTS"))
427 s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
428 else if (code10 && istag ("OBSOLETES"))
429 s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
430 else if (code10 && istag ("RECOMMENDS"))
431 s->recommends = adddep(pool, &pd, s->recommends, value, 0);
432 else if (code10 && istag ("SUGGESTS"))
433 s->suggests = adddep(pool, &pd, s->suggests, value, 0);
434 else if (code10 && istag ("SUPPLEMENTS"))
435 s->supplements = adddep(pool, &pd, s->supplements, value, 0);
436 else if (code10 && istag ("ENHANCES"))
437 s->enhances = adddep(pool, &pd, s->enhances, value, 0);
438 /* FRESHENS doesn't seem to exist. */
439 else if (code10 && istag ("TYPE"))
440 repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
442 /* XXX do something about LINGUAS and ARCH?
443 * <ma>: Don't think so. zypp does not use or propagate them.
448 fprintf (stderr, "malformed line: %s\n", line);
453 fprintf(stderr, "No product solvable created !\n");
458 s->arch = ARCH_NOARCH;
459 if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
461 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
463 s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
466 /* now for every other arch, clone the product except the architecture */
467 for ( i=0; i < numotherarchs; ++i )
469 Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
470 repodata_extend(data, p - pool->solvables);
471 /*handle = repodata_get_handle(data, p - pool->solvables - repo->start);*/
474 p->vendor = s->vendor;
475 p->arch = otherarchs[i];
478 if (p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
479 p->provides = repo_addid_dep(repo, p->provides, rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);
481 /* now merge the attributes */
482 repodata_merge_attrs(data, p - pool->solvables - repo->start, s - pool->solvables- repo->start);
486 repodata_internalize(data);