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]);
208 * add 'content' to repo
213 repo_add_content(Repo *repo, FILE *fp)
215 Pool *pool = repo->pool;
218 Solvable *s, *firsts = 0;
222 int contentstyle = 0;
224 memset(&pd, 0, sizeof(pd));
225 line = sat_malloc(1024);
229 /* use last repodata */
230 data = repo->repodata + repo->nrepodata - 1;
232 data = repo_add_repodata(repo, 0);
242 /* read line into big-enough buffer */
243 if (linep - line + 16 > aline)
245 aline = linep - line;
246 line = sat_realloc(line, aline + 512);
247 linep = line + aline;
250 if (!fgets(linep, aline - (linep - line), fp))
252 linep += strlen(linep);
253 if (linep == line || linep[-1] != '\n')
258 /* expect "key value" lines */
259 if (split (line, fields, 2) == 2)
261 char *key = fields[0];
262 char *value = fields[1];
264 fprintf (stderr, "key %s, value %s\n", key, fields[1]);
267 #define istag(x) (!strcmp (key, x))
268 #define code10 (contentstyle == 10)
269 #define code11 (contentstyle == 11)
271 if (contentstyle == 0)
273 if (istag ("CONTENTSTYLE"))
275 contentstyle = atoi(value);
282 if ((code10 && istag ("PRODUCT"))
283 || (code11 && istag ("NAME")))
285 /* Finish old solvable, but only if it wasn't created
286 on demand without seeing a PRODUCT entry. */
289 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
290 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
292 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements, 0);
293 /* Only support one product. */
294 s = pool_id2solvable(pool, repo_add_solvable(repo));
295 repodata_extend(data, s - pool->solvables);
296 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
299 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
303 /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
307 firsts = s = pool_id2solvable(pool, repo_add_solvable(repo));
308 repodata_extend(data, s - pool->solvables);
309 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
312 if (code11 && istag ("REFERENCES"))
313 repo_set_id(repo, s - pool->solvables, PRODUCT_REFERENCES, str2id(pool, value, 1));
314 else if (istag ("VERSION"))
315 s->evr = makeevr(pool, value);
316 else if (code11 && istag ("DISTRIBUTION"))
317 repo_set_str(repo, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
318 else if (code11 && istag ("FLAVOR"))
319 repo_set_str(repo, s - pool->solvables, PRODUCT_FLAVOR, value);
320 else if (istag ("DATADIR"))
321 repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
322 else if (istag ("UPDATEURLS"))
323 add_multiple_strings(data, handle, PRODUCT_UPDATEURLS, value);
324 else if (istag ("EXTRAURLS"))
325 add_multiple_strings(data, handle, PRODUCT_EXTRAURLS, value);
326 else if (istag ("OPTIONALURLS"))
327 add_multiple_strings(data, handle, PRODUCT_OPTIONALURLS, value);
328 else if (istag ("SHORTLABEL"))
329 repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
330 else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
331 repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
332 else if (!strncmp (key, "LABEL.", 6))
333 repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
334 else if (istag ("FLAGS"))
335 add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
336 else if (istag ("RELNOTESURL"))
337 repodata_add_poolstr_array(data, handle, PRODUCT_RELNOTESURL, value);
338 else if (istag ("VENDOR"))
339 s->vendor = str2id(pool, value, 1);
342 * Every tag below is Code10 only
346 else if (code10 && istag ("DISTPRODUCT"))
347 /* DISTPRODUCT is for registration and Yast, not for the solver. */
348 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
349 else if (code10 && istag ("DISTVERSION"))
350 /* DISTVERSION is for registration and Yast, not for the solver. */
351 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
352 else if (code10 && istag ("ARCH"))
353 /* Theoretically we want to have the best arch of the given
354 modifiers which still is compatible with the system
355 arch. We don't know the latter here, though. */
356 s->arch = ARCH_NOARCH;
357 else if (code10 && istag ("PREREQUIRES"))
358 s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
359 else if (code10 && istag ("REQUIRES"))
360 s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
361 else if (code10 && istag ("PROVIDES"))
362 s->provides = adddep(pool, &pd, s->provides, value, 0);
363 else if (code10 && istag ("CONFLICTS"))
364 s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
365 else if (code10 && istag ("OBSOLETES"))
366 s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
367 else if (code10 && istag ("RECOMMENDS"))
368 s->recommends = adddep(pool, &pd, s->recommends, value, 0);
369 else if (code10 && istag ("SUGGESTS"))
370 s->suggests = adddep(pool, &pd, s->suggests, value, 0);
371 else if (code10 && istag ("SUPPLEMENTS"))
372 s->supplements = adddep(pool, &pd, s->supplements, value, 0);
373 else if (code10 && istag ("ENHANCES"))
374 s->enhances = adddep(pool, &pd, s->enhances, value, 0);
375 /* FRESHENS doesn't seem to exist. */
376 else if (code10 && istag ("TYPE"))
377 repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
379 /* XXX do something about LINGUAS and ARCH?
380 * <ma>: Don't think so. zypp does not use or propagate them.
385 fprintf (stderr, "malformed line: %s\n", line);
390 fprintf(stderr, "No product solvable created !\n");
395 s->arch = ARCH_NOARCH;
396 if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
398 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
400 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements, 0);