When uniquifying properties, also sort them on the owning package.
This ensures that whenever two packages provide or (or require, obsolete
or conflict) the same property, they appear in the same order in the
propertys list of packages.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 /* Import a yum filelist as a razor package set. */
39 YUM_STATE_PACKAGE_NAME,
40 YUM_STATE_PACKAGE_ARCH,
50 XML_Parser primary_parser;
51 XML_Parser filelists_parser;
52 XML_Parser current_parser;
54 struct razor_importer *importer;
55 struct import_property_context *current_property_context;
56 char name[256], arch[64], buffer[512], *p;
58 uint32_t property_type;
63 yum_to_razor_relation (const char *flags)
65 if (flags[0] == 'L') {
67 return RAZOR_PROPERTY_LESS;
69 return RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL;
70 } else if (flags[0] == 'G') {
72 return RAZOR_PROPERTY_GREATER;
74 return RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL;
76 return RAZOR_PROPERTY_EQUAL;
80 yum_primary_start_element(void *data, const char *name, const char **atts)
82 struct yum_context *ctx = data;
83 const char *n, *epoch, *version, *release;
85 uint32_t pre, relation, flags;
88 if (strcmp(name, "name") == 0) {
89 ctx->state = YUM_STATE_PACKAGE_NAME;
91 } else if (strcmp(name, "arch") == 0) {
92 ctx->state = YUM_STATE_PACKAGE_ARCH;
94 } else if (strcmp(name, "version") == 0) {
98 for (i = 0; atts[i]; i += 2) {
99 if (strcmp(atts[i], "epoch") == 0)
101 else if (strcmp(atts[i], "ver") == 0)
102 version = atts[i + 1];
103 else if (strcmp(atts[i], "rel") == 0)
104 release = atts[i + 1];
106 if (version == NULL || release == NULL) {
107 fprintf(stderr, "invalid version tag, "
108 "missing version or release attribute\n");
112 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
113 razor_importer_begin_package(ctx->importer,
114 ctx->name, buffer, ctx->arch);
115 } else if (strcmp(name, "checksum") == 0) {
117 ctx->state = YUM_STATE_CHECKSUM;
118 } else if (strcmp(name, "rpm:requires") == 0) {
119 ctx->state = YUM_STATE_REQUIRES;
120 ctx->property_type = RAZOR_PROPERTY_REQUIRES;
121 } else if (strcmp(name, "rpm:provides") == 0) {
122 ctx->state = YUM_STATE_PROVIDES;
123 ctx->property_type = RAZOR_PROPERTY_PROVIDES;
124 } else if (strcmp(name, "rpm:obsoletes") == 0) {
125 ctx->state = YUM_STATE_OBSOLETES;
126 ctx->property_type = RAZOR_PROPERTY_OBSOLETES;
127 } else if (strcmp(name, "rpm:conflicts") == 0) {
128 ctx->state = YUM_STATE_CONFLICTS;
129 ctx->property_type = RAZOR_PROPERTY_CONFLICTS;
130 } else if (strcmp(name, "rpm:entry") == 0 &&
131 ctx->state != YUM_STATE_BEGIN) {
136 relation = RAZOR_PROPERTY_EQUAL;
138 for (i = 0; atts[i]; i += 2) {
139 if (strcmp(atts[i], "name") == 0)
141 else if (strcmp(atts[i], "epoch") == 0)
143 else if (strcmp(atts[i], "ver") == 0)
144 version = atts[i + 1];
145 else if (strcmp(atts[i], "rel") == 0)
146 release = atts[i + 1];
147 else if (strcmp(atts[i], "flags") == 0)
148 relation = yum_to_razor_relation(atts[i + 1]);
149 else if (strcmp(atts[i], "pre") == 0)
152 RAZOR_PROPERTY_POST |
153 RAZOR_PROPERTY_PREUN |
154 RAZOR_PROPERTY_POSTUN;
158 fprintf(stderr, "invalid rpm:entry, "
159 "missing name or version attributes\n");
163 razor_build_evr(buffer, sizeof buffer, epoch, version, release);
164 flags = ctx->property_type | relation | pre;
165 razor_importer_add_property(ctx->importer, n, flags, buffer);
170 yum_primary_end_element (void *data, const char *name)
172 struct yum_context *ctx = data;
174 switch (ctx->state) {
175 case YUM_STATE_PACKAGE_NAME:
176 case YUM_STATE_PACKAGE_ARCH:
177 case YUM_STATE_CHECKSUM:
179 ctx->state = YUM_STATE_BEGIN;
183 if (strcmp(name, "package") == 0) {
184 XML_StopParser(ctx->current_parser, XML_TRUE);
185 ctx->current_parser = ctx->filelists_parser;
190 yum_character_data (void *data, const XML_Char *s, int len)
192 struct yum_context *ctx = data;
194 switch (ctx->state) {
195 case YUM_STATE_PACKAGE_NAME:
196 case YUM_STATE_PACKAGE_ARCH:
197 case YUM_STATE_CHECKSUM:
199 memcpy(ctx->p, s, len);
207 yum_filelists_start_element(void *data, const char *name, const char **atts)
209 struct yum_context *ctx = data;
210 const char *pkg, *pkgid;
213 if (strcmp(name, "package") == 0) {
216 for (i = 0; atts[i]; i += 2) {
217 if (strcmp(atts[i], "name") == 0)
219 else if (strcmp(atts[i], "pkgid") == 0)
222 if (strcmp(pkgid, ctx->pkgid) != 0)
223 fprintf(stderr, "primary.xml and filelists.xml "
224 "mismatch for %s: %s vs %s",
225 pkg, pkgid, ctx->pkgid);
226 } else if (strcmp(name, "file") == 0) {
227 ctx->state = YUM_STATE_FILE;
228 ctx->p = ctx->buffer;
234 yum_filelists_end_element (void *data, const char *name)
236 struct yum_context *ctx = data;
238 ctx->state = YUM_STATE_BEGIN;
239 if (strcmp(name, "package") == 0) {
240 XML_StopParser(ctx->current_parser, XML_TRUE);
241 ctx->current_parser = ctx->primary_parser;
242 razor_importer_finish_package(ctx->importer);
243 } else if (strcmp(name, "file") == 0)
244 razor_importer_add_file(ctx->importer, ctx->buffer);
248 #define XML_BUFFER_SIZE 4096
251 razor_set_create_from_yum(void)
253 struct yum_context ctx;
256 gzFile primary, filelists;
257 XML_ParsingStatus status;
259 ctx.importer = razor_importer_create();
260 ctx.state = YUM_STATE_BEGIN;
262 ctx.primary_parser = XML_ParserCreate(NULL);
263 XML_SetUserData(ctx.primary_parser, &ctx);
264 XML_SetElementHandler(ctx.primary_parser,
265 yum_primary_start_element,
266 yum_primary_end_element);
267 XML_SetCharacterDataHandler(ctx.primary_parser,
270 ctx.filelists_parser = XML_ParserCreate(NULL);
271 XML_SetUserData(ctx.filelists_parser, &ctx);
272 XML_SetElementHandler(ctx.filelists_parser,
273 yum_filelists_start_element,
274 yum_filelists_end_element);
275 XML_SetCharacterDataHandler(ctx.filelists_parser,
278 primary = gzopen("primary.xml.gz", "rb");
281 filelists = gzopen("filelists.xml.gz", "rb");
282 if (filelists == NULL)
285 ctx.current_parser = ctx.primary_parser;
288 XML_GetParsingStatus(ctx.current_parser, &status);
289 switch (status.parsing) {
291 ret = XML_ResumeParser(ctx.current_parser);
294 case XML_INITIALIZED:
295 buf = XML_GetBuffer(ctx.current_parser,
297 if (ctx.current_parser == ctx.primary_parser)
298 len = gzread(primary, buf, XML_BUFFER_SIZE);
300 len = gzread(filelists, buf, XML_BUFFER_SIZE);
303 "couldn't read input: %s\n",
308 XML_ParseBuffer(ctx.current_parser, len, len == 0);
313 } while (status.parsing != XML_FINISHED);
316 XML_ParserFree(ctx.primary_parser);
317 XML_ParserFree(ctx.filelists_parser);
322 return razor_importer_finish(ctx.importer);