11 #define XML_BUFFER_SIZE 4096
14 parse_xml_file(const char *filename,
15 XML_StartElementHandler start,
16 XML_EndElementHandler end,
23 parser = XML_ParserCreate(NULL);
24 XML_SetElementHandler(parser, start, end);
25 XML_SetUserData(parser, data);
27 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
29 fd = open(filename, O_RDONLY);
31 fprintf(stderr, "failed to open %s: %m\n", filename);
35 while (len = read(fd, buffer, XML_BUFFER_SIZE), len > 0) {
36 err = XML_ParseBuffer(parser, len, len == 0);
37 if (err == XML_STATUS_ERROR) {
38 fprintf(stderr, "parse error at line %lu:\n%s\n",
39 XML_GetCurrentLineNumber(parser),
40 XML_ErrorString(XML_GetErrorCode(parser)));
46 fprintf(stderr, "read: %m\n");
54 struct razor_set *system_set, *repo_set, *result_set;
56 struct razor_importer *importer;
57 struct razor_set **importer_set;
59 char *install_pkgs[3], *remove_pkgs[3];
60 int n_install_pkgs, n_remove_pkgs;
62 int in_result, result_errors;
66 get_atts(const char **atts, ...)
69 const char *name, **ptr;
73 while (name = va_arg(ap, const char *), name != NULL) {
74 ptr = va_arg(ap, const char **);
76 for (i = 0; atts[i]; i += 2) {
77 if (strcmp(atts[i], name) == 0)
84 static enum razor_version_relation
85 parse_relation (const char *rel_str)
89 if (rel_str[0] == 'l')
90 return rel_str[1] == 'e' ? RAZOR_VERSION_LESS_OR_EQUAL : RAZOR_VERSION_LESS;
91 else if (rel_str[0] == 'g')
92 return rel_str[1] == 'e' ? RAZOR_VERSION_GREATER_OR_EQUAL : RAZOR_VERSION_GREATER;
93 else if (rel_str[0] == 'e' || rel_str[1] == 'q')
94 return RAZOR_VERSION_EQUAL;
100 start_test(struct test_context *ctx, const char **atts)
102 const char *name = NULL;
104 get_atts(atts, "name", &name, NULL);
106 fprintf(stderr, "Test with no name\n");
109 printf("%s\n", name);
113 end_test(struct test_context *ctx)
115 if (ctx->system_set) {
116 razor_set_destroy(ctx->system_set);
117 ctx->system_set = NULL;
120 razor_set_destroy(ctx->repo_set);
121 ctx->repo_set = NULL;
123 if (ctx->result_set) {
124 razor_set_destroy(ctx->result_set);
125 ctx->result_set = NULL;
130 start_set(struct test_context *ctx, const char **atts)
132 const char *name = NULL;
134 ctx->importer = razor_importer_new();
135 get_atts(atts, "name", &name, NULL);
137 ctx->importer_set = &ctx->result_set;
138 else if (!strcmp(name, "system"))
139 ctx->importer_set = &ctx->system_set;
140 else if (!strcmp(name, "repo"))
141 ctx->importer_set = &ctx->repo_set;
143 fprintf(stderr, " bad set name '%s'\n", name);
149 end_set(struct test_context *ctx)
151 *ctx->importer_set = razor_importer_finish(ctx->importer);
152 ctx->importer = NULL;
156 start_package(struct test_context *ctx, const char **atts)
158 const char *name = NULL, *version = NULL, *arch = NULL;
160 get_atts(atts, "name", &name, "version", &version, "arch", &arch, NULL);
162 fprintf(stderr, " package with no name\n");
166 razor_importer_begin_package(ctx->importer, name, version);
167 razor_importer_add_property(ctx->importer, name,
168 RAZOR_VERSION_EQUAL, version,
169 RAZOR_PROPERTY_PROVIDES);
173 end_package(struct test_context *ctx)
175 razor_importer_finish_package(ctx->importer);
179 start_property(struct test_context *ctx, enum razor_property_type type, const char **atts)
181 const char *name = NULL, *rel_str = NULL, *version = NULL;
182 enum razor_version_relation rel;
184 get_atts(atts, "name", &name, "rel", &rel_str, "version", &version, NULL);
186 fprintf(stderr, " no name specified for property\n");
190 rel = parse_relation(rel_str);
192 fprintf(stderr, " bad or missing version relation for property %s\n", name);
196 rel = RAZOR_VERSION_EQUAL;
198 razor_importer_add_property(ctx->importer, name,
203 start_transaction(struct test_context *ctx, const char **atts)
205 ctx->n_install_pkgs = 0;
206 ctx->n_remove_pkgs = 0;
210 end_transaction(struct test_context *ctx)
213 ctx->system_set = razor_set_update(ctx->system_set,
216 (const char **)ctx->install_pkgs);
218 while (ctx->n_install_pkgs--)
219 free(ctx->install_pkgs[ctx->n_install_pkgs]);
220 while (ctx->n_remove_pkgs--)
221 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
225 start_install_or_update(struct test_context *ctx, const char **atts)
227 const char *name = NULL;
229 get_atts(atts, "name", &name, NULL);
231 fprintf(stderr, " install/update with no name\n");
235 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
239 start_remove(struct test_context *ctx, const char **atts)
241 const char *name = NULL;
243 get_atts(atts, "name", &name, NULL);
245 fprintf(stderr, " remove with no name\n");
249 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
253 start_result(struct test_context *ctx, const char **atts)
259 diff_callback(const char *name,
260 const char *old_version, const char *new_version,
263 struct test_context *ctx = data;
265 ctx->result_errors++;
267 fprintf(stderr, " result set should not contain %s %s\n",
270 fprintf(stderr, " result set should contain %s %s\n",
276 end_result(struct test_context *ctx)
281 if (ctx->n_remove_pkgs) {
282 printf (" (ignoring because of unimplemented remove)\n");
286 if (ctx->system_set && ctx->result_set) {
287 ctx->result_errors = 0;
288 razor_set_diff(ctx->system_set, ctx->result_set,
290 if (ctx->result_errors)
297 start_unsatisfied(struct test_context *ctx, const char **atts)
300 fprintf(stderr, "Can't handle <unsatisfied>\n");
305 end_unsatisfied(struct test_context *ctx)
310 start_test_element(void *data, const char *element, const char **atts)
312 struct test_context *ctx = data;
314 if (strcmp(element, "tests") == 0) {
316 } else if (strcmp(element, "test") == 0) {
317 start_test(ctx, atts);
318 } else if (strcmp(element, "set") == 0) {
319 start_set(ctx, atts);
320 } else if (strcmp(element, "transaction") == 0) {
321 start_transaction(ctx, atts);
322 } else if (strcmp(element, "install") == 0) {
323 start_install_or_update(ctx, atts);
324 } else if (strcmp(element, "install") == 0) {
325 start_install_or_update(ctx, atts);
326 } else if (strcmp(element, "remove") == 0) {
327 start_remove(ctx, atts);
328 } else if (strcmp(element, "result") == 0) {
329 start_result(ctx, atts);
330 } else if (strcmp(element, "unsatisfied") == 0) {
331 start_unsatisfied(ctx, atts);
332 } else if (strcmp(element, "package") == 0) {
333 start_package(ctx, atts);
334 } else if (strcmp(element, "requires") == 0) {
335 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
336 } else if (strcmp(element, "provides") == 0) {
337 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
338 } else if (strcmp(element, "conflicts") == 0) {
339 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
340 } else if (strcmp(element, "obsoletes") == 0) {
341 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
343 fprintf(stderr, "Unrecognized element '%s'\n", element);
349 end_test_element (void *data, const char *element)
351 struct test_context *ctx = data;
353 if (strcmp(element, "test") == 0) {
355 } else if (strcmp(element, "set") == 0) {
357 } else if (strcmp(element, "package") == 0) {
359 } else if (strcmp(element, "transaction") == 0) {
360 end_transaction(ctx);
361 } else if (strcmp(element, "result") == 0) {
363 } else if (strcmp(element, "unsatisfied") == 0) {
364 end_unsatisfied(ctx);
368 int main(int argc, char *argv[])
370 struct test_context ctx;
373 fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
377 memset(&ctx, 0, sizeof ctx);
378 parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);