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. */
115 words += split(line, sp + words, 4 - words);
118 /* Hack, as the content file adds 'package:' for package
119 dependencies sometimes. */
120 if (!strncmp (sp[0], "package:", 8))
122 id = str2id(pool, sp[0], 1);
123 if (words >= 3 && strpbrk (sp[1], "<>="))
125 evrid = makeevr(pool, sp[2]);
126 for (flags = 0; flags < 6; flags++)
127 if (!strcmp(sp[1], flagtab[flags]))
131 fprintf(stderr, "Unknown relation '%s'\n", sp[1]);
134 id = rel2id(pool, id, evrid, flags + 1, 1);
135 /* Consume three words, there's nothing to move to front. */
143 /* Consume one word. If we had more move them to front. */
145 for (j = 0; j < words; j++)
148 line = sp[2], words = 2;
150 olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
151 if (! ( line || words > 0 ) )
158 add_multiple_strings(Repodata *data, Id handle, Id name, char *value)
163 int words = split(value, sp, 2);
166 repodata_add_poolstr_array(data, handle, name, sp[0]);
174 repo_add_content(Repo *repo, FILE *fp)
176 Pool *pool = repo->pool;
179 Solvable *s, *firsts = 0;
184 memset(&pd, 0, sizeof(pd));
185 line = sat_malloc(1024);
189 /* use last repodata */
190 data = repo->repodata + repo->nrepodata - 1;
192 data = repo_add_repodata(repo, 0);
201 if (linep - line + 16 > aline)
203 aline = linep - line;
204 line = sat_realloc(line, aline + 512);
205 linep = line + aline;
208 if (!fgets(linep, aline - (linep - line), fp))
210 linep += strlen(linep);
211 if (linep == line || linep[-1] != '\n')
215 if (split (line, fields, 2) == 2)
217 char *key = fields[0];
218 char *value = fields[1];
220 fprintf (stderr, "key %s, value %s\n", key, fields[1]);
223 #define istag(x) !strcmp (key, x)
224 if (istag ("PRODUCT"))
226 /* Finish old solvable, but only if it wasn't created
227 on demand without seeing a PRODUCT entry. */
230 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
231 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
233 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
234 /* Only support one product. */
235 s = pool_id2solvable(pool, repo_add_solvable(repo));
236 repodata_extend(data, s - pool->solvables);
237 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
240 s->name = str2id(pool, join(&pd, "product", ":", value), 1);
244 /* Sometimes PRODUCT is not the first entry, but we need a solvable
248 firsts = s = pool_id2solvable(pool, repo_add_solvable(repo));
249 repodata_extend(data, s - pool->solvables);
250 handle = repodata_get_handle(data, s - pool->solvables - repo->start);
252 if (istag ("VERSION"))
253 /* without a release? but that's like zypp implements it */
254 s->evr = makeevr(pool, value);
255 else if (istag ("DISTPRODUCT"))
256 /* DISTPRODUCT is for registration and Yast, not for the solver. */
257 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
258 else if (istag ("DISTVERSION"))
259 /* DISTVERSION is for registration and Yast, not for the solver. */
260 repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
261 else if (istag ("VENDOR"))
262 s->vendor = str2id(pool, value, 1);
263 else if (istag ("ARCH"))
264 /* Theoretically we want to have the best arch of the given
265 modifiers which still is compatible with the system
266 arch. We don't know the latter here, though. */
267 s->arch = ARCH_NOARCH;
268 else if (istag ("PREREQUIRES"))
269 s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
270 else if (istag ("REQUIRES"))
271 s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
272 else if (istag ("PROVIDES"))
273 s->provides = adddep(pool, &pd, s->provides, value, 0);
274 else if (istag ("CONFLICTS"))
275 s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
276 else if (istag ("OBSOLETES"))
277 s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
278 else if (istag ("RECOMMENDS"))
279 s->recommends = adddep(pool, &pd, s->recommends, value, 0);
280 else if (istag ("SUGGESTS"))
281 s->suggests = adddep(pool, &pd, s->suggests, value, 0);
282 else if (istag ("SUPPLEMENTS"))
283 s->supplements = adddep(pool, &pd, s->supplements, value, 0);
284 else if (istag ("ENHANCES"))
285 s->enhances = adddep(pool, &pd, s->enhances, value, 0);
286 else if (istag ("DATADIR"))
287 repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
288 /* FRESHENS doesn't seem to exist. */
289 else if (istag ("TYPE"))
290 repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
291 else if (istag ("RELNOTESURL"))
292 repodata_add_poolstr_array(data, handle, PRODUCT_RELNOTESURL, value);
293 else if (istag ("UPDATEURLS"))
294 add_multiple_strings(data, handle, PRODUCT_UPDATEURLS, value);
295 else if (istag ("EXTRAURLS"))
296 add_multiple_strings(data, handle, PRODUCT_EXTRAURLS, value);
297 else if (istag ("OPTIONALURLS"))
298 add_multiple_strings(data, handle, PRODUCT_OPTIONALURLS, value);
299 else if (istag ("SHORTLABEL"))
300 repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
301 else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
302 repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
303 else if (!strncmp (key, "LABEL.", 6))
304 repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
305 else if (istag ("FLAGS"))
306 add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
308 /* XXX do something about LINGUAS and ARCH?
309 * <ma>: Don't think so. zypp does not use or propagate them.
314 fprintf (stderr, "malformed line: %s\n", line);
318 s->arch = ARCH_NOARCH;
319 if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
320 s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
322 s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);