2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
19 #include "repo_content.h"
22 split(char *l, char **sp, int m)
27 while (*l == ' ' || *l == '\t')
34 while (*l && !(*l == ' ' || *l == '\t'))
50 makeevr(Pool *pool, char *s)
52 if (!strncmp(s, "0:", 2) && s[2])
54 return str2id(pool, s, 1);
57 static char *flagtab[] = {
67 join(struct parsedata *pd, char *s1, char *s2, char *s3)
81 pd->tmp = sat_realloc(pd->tmp, pd->tmpl);
103 adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker)
112 /* Name [relop evr] [rest] --> 1, 2, 3 or 4 fields. */
113 words += split(line, sp + words, 4 - words);
115 /* Hack, as the content file adds 'package:' for package
116 dependencies sometimes. */
117 if (!strncmp (sp[0], "package:", 8))
119 id = str2id(pool, sp[0], 1);
120 if (words >= 3 && strpbrk (sp[1], "<>="))
122 evrid = makeevr(pool, sp[2]);
123 for (flags = 0; flags < 6; flags++)
124 if (!strcmp(sp[1], flagtab[flags]))
128 fprintf(stderr, "Unknown relation '%s'\n", sp[1]);
131 id = rel2id(pool, id, evrid, flags + 1, 1);
132 /* Consume three words, there's nothing to move to front. */
134 line = sp[3], words = 0;
139 /* Consume one word. If we had more move them to front. */
141 for (j = 0; j < words; j++)
144 line = sp[2], words = 2;
146 olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
154 add_multiple_strings(Repodata *data, Id handle, Id name, char *value)
159 int words = split(value, sp, 2);
162 repodata_add_poolstr_array(data, handle, name, sp[0]);
170 repo_add_content(Repo *repo, FILE *fp)
172 Pool *pool = repo->pool;
175 Solvable *s, *firsts = 0;
180 memset(&pd, 0, sizeof(pd));
181 line = sat_malloc(1024);
185 /* use last repodata */
186 data = repo->repodata + repo->nrepodata - 1;
188 data = repo_add_repodata(repo, 0);
197 if (linep - line + 16 > aline)
199 aline = linep - line;
200 line = sat_realloc(line, aline + 512);
201 linep = line + aline;
204 if (!fgets(linep, aline - (linep - line), fp))
206 linep += strlen(linep);
207 if (linep == line || linep[-1] != '\n')
211 if (split (line, fields, 2) == 2)
213 char *key = fields[0];
214 char *value = fields[1];
215 char *modifier = strchr (key, '.');
220 fprintf (stderr, "key %s, mod %s, value %s\n", key, modifier, fields[1]);
222 fprintf (stderr, "key %s, value %s\n", key, fields[1]);
225 #define istag(x) !strcmp (key, x)
226 if (istag ("PRODUCT"))
228 /* Finish old solvable, but only if it wasn't created
229 on demand without seeing a PRODUCT entry. */
232 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
233 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
235 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
236 /* Only support one product. */
237 s = pool_id2solvable(pool, repo_add_solvable(repo));
238 repodata_extend(data, s - pool->solvables);
239 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
242 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
246 /* Sometimes PRODUCT is not the first entry, but we need a solvable
250 firsts = s = pool_id2solvable(pool, repo_add_solvable(repo));
251 repodata_extend(data, s - pool->solvables);
252 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
254 if (istag ("VERSION"))
255 /* without a release? but that's like zypp implements it */
256 s->evr = makeevr(pool, value);
257 else if (istag ("DISTPRODUCT"))
258 /* DISTPRODUCT is for registration and Yast, not for the solver. */
259 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
260 else if (istag ("DISTVERSION"))
261 /* DISTVERSION is for registration and Yast, not for the solver. */
262 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
263 else if (istag ("VENDOR"))
264 s->vendor = str2id(pool, value, 1);
265 else if (istag ("ARCH"))
266 /* Theoretically we want to have the best arch of the given
267 modifiers which still is compatible with the system
268 arch. We don't know the latter here, though. */
269 s->arch = ARCH_NOARCH;
270 else if (istag ("PREREQUIRES"))
271 s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
272 else if (istag ("REQUIRES"))
273 s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
274 else if (istag ("PROVIDES"))
275 s->provides = adddep(pool, &pd, s->provides, value, 0);
276 else if (istag ("CONFLICTS"))
277 s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
278 else if (istag ("OBSOLETES"))
279 s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
280 else if (istag ("RECOMMENDS"))
281 s->recommends = adddep(pool, &pd, s->recommends, value, 0);
282 else if (istag ("SUGGESTS"))
283 s->suggests = adddep(pool, &pd, s->suggests, value, 0);
284 else if (istag ("SUPPLEMENTS"))
285 s->supplements = adddep(pool, &pd, s->supplements, value, 0);
286 else if (istag ("ENHANCES"))
287 s->enhances = adddep(pool, &pd, s->enhances, value, 0);
288 else if (istag ("DATADIR"))
289 repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
290 /* FRESHENS doesn't seem to exist. */
291 else if (istag ("TYPE"))
292 repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
293 else if (istag ("RELNOTESURL"))
294 repodata_add_poolstr_array(data, handle, PRODUCT_RELNOTESURL, value);
295 else if (istag ("UPDATEURLS"))
296 add_multiple_strings(data, handle, PRODUCT_UPDATEURLS, value);
297 else if (istag ("EXTRAURLS"))
298 add_multiple_strings(data, handle, PRODUCT_EXTRAURLS, value);
299 else if (istag ("OPTIONALURLS"))
300 add_multiple_strings(data, handle, PRODUCT_OPTIONALURLS, value);
301 else if (istag ("SHORTLABEL"))
302 repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
303 else if (istag ("LABEL"))
304 repo_set_str(repo, s - pool->solvables, PRODUCT_LABEL, value);
305 else if (!strncmp (key, "LABEL.", 6))
306 repo_set_str(repo, s - pool->solvables, str2id(pool, join(&pd, "product:label:", key + 6, 0), 1), value);
307 else if (istag ("FLAGS"))
308 add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
310 /* XXX do something about LINGUAS and ARCH? */
314 fprintf (stderr, "malformed line: %s\n", line);
317 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
318 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
320 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);