Add support for preloading lua modules. This is useful both when
providing lua bindings to applications based on librazor and when
producing static binaries using librazor (where otherwise the lua
POSIX library would need to be included as an additional dynamic
object).
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.
30 #define XML_BUFFER_SIZE 4096
33 parse_xml_file(const char *filename,
34 XML_StartElementHandler start,
35 XML_EndElementHandler end,
42 parser = XML_ParserCreate(NULL);
43 XML_SetElementHandler(parser, start, end);
44 XML_SetUserData(parser, data);
46 fd = open(filename, O_RDONLY);
48 fprintf(stderr, "failed to open %s: %s\n", filename,
54 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
55 len = read(fd, buffer, XML_BUFFER_SIZE);
58 err = XML_ParseBuffer(parser, len, len == 0);
59 if (err == XML_STATUS_ERROR) {
60 fprintf(stderr, "parse error at line %lu:\n%s\n",
61 XML_GetCurrentLineNumber(parser),
62 XML_ErrorString(XML_GetErrorCode(parser)));
76 struct razor_set *system_set, *repo_set, *result_set;
78 struct razor_importer *importer;
79 struct razor_set **importer_set;
81 struct razor_transaction *trans;
83 char *install_pkgs[3], *remove_pkgs[3];
84 int n_install_pkgs, n_remove_pkgs;
93 get_atts(const char **atts, ...)
96 const char *name, **ptr;
100 while (name = va_arg(ap, const char *), name != NULL) {
101 ptr = va_arg(ap, const char **);
103 for (i = 0; atts[i]; i += 2) {
104 if (strcmp(atts[i], name) == 0)
111 static enum razor_property_flags
112 parse_relation (const char *rel_str)
116 if (rel_str[0] == 'L')
117 return rel_str[1] == 'E' ? RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_LESS;
118 else if (rel_str[0] == 'G')
119 return rel_str[1] == 'E' ? RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_GREATER;
120 else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
121 return RAZOR_PROPERTY_EQUAL;
127 start_test(struct test_context *ctx, const char **atts)
129 const char *name = NULL;
131 get_atts(atts, "name", &name, NULL);
133 fprintf(stderr, "Test with no name\n");
136 printf("%s\n", name);
140 end_test(struct test_context *ctx)
142 if (ctx->system_set) {
143 razor_set_destroy(ctx->system_set);
144 ctx->system_set = NULL;
147 razor_set_destroy(ctx->repo_set);
148 ctx->repo_set = NULL;
150 if (ctx->result_set) {
151 razor_set_destroy(ctx->result_set);
152 ctx->result_set = NULL;
155 razor_transaction_destroy(ctx->trans);
161 start_set(struct test_context *ctx, const char **atts)
163 const char *name = NULL;
165 ctx->importer = razor_importer_create();
166 get_atts(atts, "name", &name, NULL);
168 ctx->importer_set = &ctx->result_set;
169 else if (!strcmp(name, "system"))
170 ctx->importer_set = &ctx->system_set;
171 else if (!strcmp(name, "repo"))
172 ctx->importer_set = &ctx->repo_set;
174 fprintf(stderr, " bad set name '%s'\n", name);
180 end_set(struct test_context *ctx)
182 *ctx->importer_set = razor_importer_finish(ctx->importer);
183 ctx->importer = NULL;
187 start_package(struct test_context *ctx, const char **atts)
189 const char *name = NULL, *version = NULL, *arch = NULL;
191 get_atts(atts, "name", &name,
197 fprintf(stderr, " package with no name\n");
201 razor_importer_begin_package(ctx->importer, name, version, arch);
202 razor_importer_add_property(ctx->importer, name,
203 RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_PROVIDES,
208 end_package(struct test_context *ctx)
210 razor_importer_finish_package(ctx->importer);
214 add_property(struct test_context *ctx, enum razor_property_flags type, const char *name, enum razor_property_flags rel, const char *version)
216 razor_importer_add_property(ctx->importer, name,
217 rel | type, version);
221 razor_property_flags_relation_to_string(enum razor_property_flags rel)
223 if (rel == RAZOR_PROPERTY_LESS)
225 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_LESS))
227 if (rel == RAZOR_PROPERTY_EQUAL)
229 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_GREATER))
231 if (rel == RAZOR_PROPERTY_GREATER)
238 check_unsatisfiable_property(struct test_context *ctx,
239 enum razor_property_flags type,
241 enum razor_property_flags rel,
247 if (razor_transaction_unsatisfied_property(ctx->trans,
248 name, rel | type, version))
251 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
252 name, razor_property_flags_relation_to_string(rel), version);
257 start_property(struct test_context *ctx, enum razor_property_flags type, const char **atts)
259 const char *name = NULL, *rel_str = NULL, *version = NULL;
260 enum razor_property_flags rel;
262 get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
264 fprintf(stderr, " no name specified for property\n");
268 rel = parse_relation(rel_str);
270 fprintf(stderr, " bad or missing version relation for property %s\n", name);
274 rel = RAZOR_PROPERTY_EQUAL;
277 check_unsatisfiable_property(ctx, type, name, rel, version);
279 add_property(ctx, type, name, rel, version);
283 start_transaction(struct test_context *ctx, const char **atts)
285 ctx->n_install_pkgs = 0;
286 ctx->n_remove_pkgs = 0;
289 static struct razor_package *
290 get_package(struct razor_set *set, const char *package)
292 struct razor_package_iterator *pi;
293 struct razor_package *p;
294 const char *name, *version, *arch;
296 pi = razor_package_iterator_create(set);
297 while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_NAME, &name,
298 RAZOR_DETAIL_VERSION, &version,
299 RAZOR_DETAIL_ARCH, &arch,
300 RAZOR_DETAIL_LAST)) {
301 if (strcmp(package, name) == 0)
304 razor_package_iterator_destroy(pi);
310 end_transaction(struct test_context *ctx)
312 struct razor_package *pkg;
315 ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
316 for (i = 0; i < ctx->n_install_pkgs; i++) {
317 pkg = get_package(ctx->repo_set, ctx->install_pkgs[i]);
318 razor_transaction_install_package(ctx->trans, pkg);
320 for (i = 0; i < ctx->n_remove_pkgs; i++) {
321 pkg = get_package(ctx->system_set, ctx->remove_pkgs[i]);
323 pkg = get_package(ctx->repo_set, ctx->remove_pkgs[i]);
325 razor_transaction_remove_package(ctx->trans, pkg);
328 razor_transaction_resolve(ctx->trans);
329 errors = razor_transaction_describe(ctx->trans);
332 while (ctx->n_install_pkgs--)
333 free(ctx->install_pkgs[ctx->n_install_pkgs]);
334 while (ctx->n_remove_pkgs--)
335 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
338 struct razor_set *new;
339 new = razor_transaction_finish(ctx->trans);
341 ctx->system_set = new;
346 start_install_or_update(struct test_context *ctx, const char **atts)
348 const char *name = NULL;
350 get_atts(atts, "name", &name, NULL);
352 fprintf(stderr, " install/update with no name\n");
356 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
360 start_remove(struct test_context *ctx, const char **atts)
362 const char *name = NULL;
364 get_atts(atts, "name", &name, NULL);
366 fprintf(stderr, " remove with no name\n");
370 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
374 start_result(struct test_context *ctx, const char **atts)
380 diff_callback(enum razor_diff_action action,
381 struct razor_package *package,
387 struct test_context *ctx = data;
390 if (action == RAZOR_DIFF_ACTION_REMOVE) {
391 fprintf(stderr, " result set should not contain %s %s\n",
394 fprintf(stderr, " result set should contain %s %s\n",
400 end_result(struct test_context *ctx)
404 if (ctx->result_set) {
405 if (!ctx->system_set)
406 ctx->system_set = razor_set_create();
407 razor_set_diff(ctx->system_set, ctx->result_set,
413 start_unsatisfiable(struct test_context *ctx, const char **atts)
415 if (ctx->result_set) {
416 fprintf(stderr, "Expected to fail, but didn't\n");
424 end_unsatisfiable(struct test_context *ctx)
430 start_test_element(void *data, const char *element, const char **atts)
432 struct test_context *ctx = data;
434 if (strcmp(element, "tests") == 0) {
436 } else if (strcmp(element, "test") == 0) {
437 start_test(ctx, atts);
438 } else if (strcmp(element, "set") == 0) {
439 start_set(ctx, atts);
440 } else if (strcmp(element, "transaction") == 0) {
441 start_transaction(ctx, atts);
442 } else if (strcmp(element, "install") == 0) {
443 start_install_or_update(ctx, atts);
444 } else if (strcmp(element, "install") == 0) {
445 start_install_or_update(ctx, atts);
446 } else if (strcmp(element, "remove") == 0) {
447 start_remove(ctx, atts);
448 } else if (strcmp(element, "result") == 0) {
449 start_result(ctx, atts);
450 } else if (strcmp(element, "unsatisfiable") == 0) {
451 start_unsatisfiable(ctx, atts);
452 } else if (strcmp(element, "package") == 0) {
453 start_package(ctx, atts);
454 } else if (strcmp(element, "requires") == 0) {
455 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
456 } else if (strcmp(element, "provides") == 0) {
457 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
458 } else if (strcmp(element, "conflicts") == 0) {
459 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
460 } else if (strcmp(element, "obsoletes") == 0) {
461 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
463 fprintf(stderr, "Unrecognized element '%s'\n", element);
469 end_test_element (void *data, const char *element)
471 struct test_context *ctx = data;
473 if (strcmp(element, "test") == 0) {
475 } else if (strcmp(element, "set") == 0) {
477 } else if (strcmp(element, "package") == 0) {
479 } else if (strcmp(element, "transaction") == 0) {
480 end_transaction(ctx);
481 } else if (strcmp(element, "result") == 0) {
483 } else if (strcmp(element, "unsatisfiable") == 0) {
484 end_unsatisfiable(ctx);
488 int main(int argc, char *argv[])
490 struct test_context ctx;
491 const char *test_file;
493 memset(&ctx, 0, sizeof ctx);
496 fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
500 if (argc >= 2 && !strcmp (argv[1], "-d")) {
508 test_file = "test.xml";
510 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
513 fprintf(stderr, "\n%d errors\n", ctx.errors);