4 * Parses RedHat comps format
6 * Copyright (c) 2012, Novell Inc.
8 * This program is licensed under the BSD license, read LICENSE.BSD
9 * for further information
12 #include <sys/types.h>
23 #include "solv_xmlparser.h"
25 #include "tools_util.h"
26 #include "repo_comps.h"
31 * what's the difference between group/category?
32 * handle "default" and "langonly".
34 * maybe handle REL_COND in solver recommends handling?
61 static struct solv_xmlparser_element stateswitches[] = {
62 { STATE_START, "comps", STATE_COMPS, 0 },
63 { STATE_COMPS, "group", STATE_GROUP, 0 },
64 { STATE_COMPS, "category", STATE_CATEGORY, 0 },
65 { STATE_GROUP, "id", STATE_ID, 1 },
66 { STATE_GROUP, "name", STATE_NAME, 1 },
67 { STATE_GROUP, "description", STATE_DESCRIPTION, 1 },
68 { STATE_GROUP, "uservisible", STATE_USERVISIBLE, 1 },
69 { STATE_GROUP, "display_order", STATE_DISPLAY_ORDER, 1 },
70 { STATE_GROUP, "default", STATE_DEFAULT, 1 },
71 { STATE_GROUP, "langonly", STATE_LANGONLY, 1 },
72 { STATE_GROUP, "lang_only", STATE_LANG_ONLY, 1 },
73 { STATE_GROUP, "packagelist", STATE_PACKAGELIST, 0 },
74 { STATE_PACKAGELIST, "packagereq", STATE_PACKAGEREQ, 1 },
75 { STATE_CATEGORY, "id", STATE_ID, 1 },
76 { STATE_CATEGORY, "name", STATE_NAME, 1 },
77 { STATE_CATEGORY, "description", STATE_DESCRIPTION, 1 },
78 { STATE_CATEGORY , "grouplist", STATE_GROUPLIST, 0 },
79 { STATE_CATEGORY , "display_order", STATE_DISPLAY_ORDER, 1 },
80 { STATE_GROUPLIST, "groupid", STATE_GROUPID, 1 },
91 struct solv_xmlparser xmlp;
106 startElement(struct solv_xmlparser *xmlp, int state, const char *name, const char **atts)
108 struct parsedata *pd = xmlp->userdata;
109 Pool *pool = pd->pool;
116 s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
117 pd->handle = s - pool->solvables;
118 pd->kind = state == STATE_GROUP ? "group" : "category";
123 case STATE_DESCRIPTION:
124 case STATE_CDESCRIPTION:
125 pd->tmplang = join_dup(&pd->jd, solv_xmlparser_find_attr("xml:lang", atts));
128 case STATE_PACKAGEREQ:
130 const char *type = solv_xmlparser_find_attr("type", atts);
132 pd->reqtype = SOLVABLE_RECOMMENDS;
133 if (type && !strcmp(type, "conditional"))
135 const char *requires = solv_xmlparser_find_attr("requires", atts);
136 if (requires && *requires)
137 pd->condreq = pool_str2id(pool, requires, 1);
139 else if (type && !strcmp(type, "mandatory"))
140 pd->reqtype = SOLVABLE_REQUIRES;
141 else if (type && !strcmp(type, "optional"))
142 pd->reqtype = SOLVABLE_SUGGESTS;
153 endElement(struct solv_xmlparser *xmlp, int state, char *content)
155 struct parsedata *pd = xmlp->userdata;
156 Solvable *s = pd->solvable;
164 s->arch = ARCH_NOARCH;
167 if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
168 s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
173 s->name = pool_str2id(pd->pool, join2(&pd->jd, pd->kind, ":", content), 1);
177 repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_SUMMARY, pd->tmplang, 1), content);
180 case STATE_DESCRIPTION:
181 repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_DESCRIPTION, pd->tmplang, 1), content);
184 case STATE_PACKAGEREQ:
185 id = pool_str2id(pd->pool, content, 1);
187 id = pool_rel2id(pd->pool, id, pd->condreq, REL_COND, 1);
188 repo_add_idarray(pd->repo, pd->handle, pd->reqtype, id);
192 id = pool_str2id(pd->pool, join2(&pd->jd, "group", ":", content), 1);
193 s->requires = repo_addid_dep(pd->repo, s->requires, id, 0);
196 case STATE_USERVISIBLE:
197 repodata_set_void(pd->data, pd->handle, SOLVABLE_ISVISIBLE);
200 case STATE_DISPLAY_ORDER:
201 repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, content);
210 repo_add_comps(Repo *repo, FILE *fp, int flags)
215 data = repo_add_repodata(repo, flags);
217 memset(&pd, 0, sizeof(pd));
219 pd.pool = repo->pool;
221 solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement);
222 if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK)
223 pool_debug(pd.pool, SOLV_ERROR, "repo_comps: %s at line %u:%u\n", pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column);
224 solv_xmlparser_free(&pd.xmlp);
225 join_freemem(&pd.jd);
227 if (!(flags & REPO_NO_INTERNALIZE))
228 repodata_internalize(data);