Only export symbols starting with razor_ in dynamic library.
Apart from being good practice to avoid clashes with higher-level
libraries and the application, this also fixes an obscure bug: The
gnulib library is used both by librazor (the dynamic library) and
by razor (the executable). In doing so, we want to have two separate
copies of the library despite the code duplication this involves.
Without the explicit limit to export only razor_ symbols, the razor
executable under mingw64 was picking up the getopt_long function
from librazor and the optind variable from libgnu which meant that
it did not see optind changing. Hiding librazor's copy of getopt
causes the linker to find libgnu's copy and everything works.
Note that under mingw librazor-#.dll still contains undocumented
(private) razor_ symbols but these will do no harm as long as nobody
tries to use them.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #define XML_BUFFER_SIZE 4096
35 parse_xml_file(const char *filename,
36 XML_StartElementHandler start,
37 XML_EndElementHandler end,
44 parser = XML_ParserCreate(NULL);
45 XML_SetElementHandler(parser, start, end);
46 XML_SetUserData(parser, data);
48 fd = open(filename, O_RDONLY);
50 fprintf(stderr, "failed to open %s: %s\n", filename,
56 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
57 len = read(fd, buffer, XML_BUFFER_SIZE);
60 err = XML_ParseBuffer(parser, len, len == 0);
61 if (err == XML_STATUS_ERROR) {
62 fprintf(stderr, "parse error at line %lu:\n%s\n",
63 XML_GetCurrentLineNumber(parser),
64 XML_ErrorString(XML_GetErrorCode(parser)));
78 struct razor_set *system_set, *repo_set, *result_set;
80 struct razor_importer *importer;
81 struct razor_set **importer_set;
83 struct razor_transaction *trans;
85 char *install_pkgs[3], *remove_pkgs[3];
86 int n_install_pkgs, n_remove_pkgs;
95 get_atts(const char **atts, ...)
98 const char *name, **ptr;
102 while (name = va_arg(ap, const char *), name != NULL) {
103 ptr = va_arg(ap, const char **);
105 for (i = 0; atts[i]; i += 2) {
106 if (strcmp(atts[i], name) == 0)
113 static enum razor_property_flags
114 parse_relation (const char *rel_str)
118 if (rel_str[0] == 'L')
119 return rel_str[1] == 'E' ? RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_LESS;
120 else if (rel_str[0] == 'G')
121 return rel_str[1] == 'E' ? RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_GREATER;
122 else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
123 return RAZOR_PROPERTY_EQUAL;
129 start_test(struct test_context *ctx, const char **atts)
131 const char *name = NULL;
133 get_atts(atts, "name", &name, NULL);
135 fprintf(stderr, "Test with no name\n");
138 printf("%s\n", name);
142 end_test(struct test_context *ctx)
144 if (ctx->system_set) {
145 razor_set_unref(ctx->system_set);
146 ctx->system_set = NULL;
149 razor_set_unref(ctx->repo_set);
150 ctx->repo_set = NULL;
152 if (ctx->result_set) {
153 razor_set_unref(ctx->result_set);
154 ctx->result_set = NULL;
157 razor_transaction_destroy(ctx->trans);
163 start_set(struct test_context *ctx, const char **atts)
165 const char *name = NULL;
167 ctx->importer = razor_importer_create();
168 get_atts(atts, "name", &name, NULL);
170 ctx->importer_set = &ctx->result_set;
171 else if (!strcmp(name, "system"))
172 ctx->importer_set = &ctx->system_set;
173 else if (!strcmp(name, "repo"))
174 ctx->importer_set = &ctx->repo_set;
176 fprintf(stderr, " bad set name '%s'\n", name);
182 end_set(struct test_context *ctx)
184 *ctx->importer_set = razor_importer_finish(ctx->importer);
185 ctx->importer = NULL;
189 start_package(struct test_context *ctx, const char **atts)
191 const char *name = NULL, *version = NULL, *arch = NULL;
193 get_atts(atts, "name", &name,
199 fprintf(stderr, " package with no name\n");
203 razor_importer_begin_package(ctx->importer, name, version, arch);
204 razor_importer_add_property(ctx->importer, name,
205 RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_PROVIDES,
210 end_package(struct test_context *ctx)
212 razor_importer_finish_package(ctx->importer);
216 add_property(struct test_context *ctx, enum razor_property_flags type, const char *name, enum razor_property_flags rel, const char *version)
218 razor_importer_add_property(ctx->importer, name,
219 rel | type, version);
223 razor_property_flags_relation_to_string(enum razor_property_flags rel)
225 if (rel == RAZOR_PROPERTY_LESS)
227 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_LESS))
229 if (rel == RAZOR_PROPERTY_EQUAL)
231 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_GREATER))
233 if (rel == RAZOR_PROPERTY_GREATER)
240 check_unsatisfiable_property(struct test_context *ctx,
241 enum razor_property_flags type,
243 enum razor_property_flags rel,
249 if (razor_transaction_unsatisfied_property(ctx->trans,
250 name, rel | type, version))
253 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
254 name, razor_property_flags_relation_to_string(rel), version);
259 start_property(struct test_context *ctx, enum razor_property_flags type, const char **atts)
261 const char *name = NULL, *rel_str = NULL, *version = NULL;
262 enum razor_property_flags rel;
264 get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
266 fprintf(stderr, " no name specified for property\n");
270 rel = parse_relation(rel_str);
272 fprintf(stderr, " bad or missing version relation for property %s\n", name);
276 rel = RAZOR_PROPERTY_EQUAL;
279 check_unsatisfiable_property(ctx, type, name, rel, version);
281 add_property(ctx, type, name, rel, version);
285 start_transaction(struct test_context *ctx, const char **atts)
287 ctx->n_install_pkgs = 0;
288 ctx->n_remove_pkgs = 0;
291 static struct razor_package *
292 get_package(struct razor_set *set, const char *package)
294 struct razor_package_iterator *pi;
295 struct razor_package *p;
296 const char *name, *version, *arch;
298 pi = razor_package_iterator_create(set);
299 while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_NAME, &name,
300 RAZOR_DETAIL_VERSION, &version,
301 RAZOR_DETAIL_ARCH, &arch,
302 RAZOR_DETAIL_LAST)) {
303 if (strcmp(package, name) == 0)
306 razor_package_iterator_destroy(pi);
312 end_transaction(struct test_context *ctx)
314 struct razor_package *pkg;
317 ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
318 for (i = 0; i < ctx->n_install_pkgs; i++) {
319 pkg = get_package(ctx->repo_set, ctx->install_pkgs[i]);
320 razor_transaction_install_package(ctx->trans, pkg);
322 for (i = 0; i < ctx->n_remove_pkgs; i++) {
323 pkg = get_package(ctx->system_set, ctx->remove_pkgs[i]);
325 pkg = get_package(ctx->repo_set, ctx->remove_pkgs[i]);
327 razor_transaction_remove_package(ctx->trans, pkg);
330 razor_transaction_resolve(ctx->trans);
331 errors = razor_transaction_describe(ctx->trans);
334 while (ctx->n_install_pkgs--)
335 free(ctx->install_pkgs[ctx->n_install_pkgs]);
336 while (ctx->n_remove_pkgs--)
337 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
340 struct razor_set *new;
341 new = razor_transaction_commit(ctx->trans);
342 razor_transaction_destroy(ctx->trans);
344 ctx->system_set = new;
349 start_install_or_update(struct test_context *ctx, const char **atts)
351 const char *name = NULL;
353 get_atts(atts, "name", &name, NULL);
355 fprintf(stderr, " install/update with no name\n");
359 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
363 start_remove(struct test_context *ctx, const char **atts)
365 const char *name = NULL;
367 get_atts(atts, "name", &name, NULL);
369 fprintf(stderr, " remove with no name\n");
373 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
377 start_result(struct test_context *ctx, const char **atts)
383 diff_callback(enum razor_diff_action action,
384 struct razor_package *package,
390 struct test_context *ctx = data;
393 if (action == RAZOR_DIFF_ACTION_REMOVE) {
394 fprintf(stderr, " result set should not contain %s %s\n",
397 fprintf(stderr, " result set should contain %s %s\n",
403 end_result(struct test_context *ctx)
407 if (ctx->result_set) {
408 if (!ctx->system_set)
409 ctx->system_set = razor_set_create();
410 razor_set_diff(ctx->system_set, ctx->result_set,
416 start_unsatisfiable(struct test_context *ctx, const char **atts)
418 if (ctx->result_set) {
419 fprintf(stderr, "Expected to fail, but didn't\n");
427 end_unsatisfiable(struct test_context *ctx)
433 start_test_element(void *data, const char *element, const char **atts)
435 struct test_context *ctx = data;
437 if (strcmp(element, "tests") == 0) {
439 } else if (strcmp(element, "test") == 0) {
440 start_test(ctx, atts);
441 } else if (strcmp(element, "set") == 0) {
442 start_set(ctx, atts);
443 } else if (strcmp(element, "transaction") == 0) {
444 start_transaction(ctx, atts);
445 } else if (strcmp(element, "install") == 0) {
446 start_install_or_update(ctx, atts);
447 } else if (strcmp(element, "install") == 0) {
448 start_install_or_update(ctx, atts);
449 } else if (strcmp(element, "remove") == 0) {
450 start_remove(ctx, atts);
451 } else if (strcmp(element, "result") == 0) {
452 start_result(ctx, atts);
453 } else if (strcmp(element, "unsatisfiable") == 0) {
454 start_unsatisfiable(ctx, atts);
455 } else if (strcmp(element, "package") == 0) {
456 start_package(ctx, atts);
457 } else if (strcmp(element, "requires") == 0) {
458 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
459 } else if (strcmp(element, "provides") == 0) {
460 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
461 } else if (strcmp(element, "conflicts") == 0) {
462 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
463 } else if (strcmp(element, "obsoletes") == 0) {
464 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
466 fprintf(stderr, "Unrecognized element '%s'\n", element);
472 end_test_element (void *data, const char *element)
474 struct test_context *ctx = data;
476 if (strcmp(element, "test") == 0) {
478 } else if (strcmp(element, "set") == 0) {
480 } else if (strcmp(element, "package") == 0) {
482 } else if (strcmp(element, "transaction") == 0) {
483 end_transaction(ctx);
484 } else if (strcmp(element, "result") == 0) {
486 } else if (strcmp(element, "unsatisfiable") == 0) {
487 end_unsatisfiable(ctx);
491 int main(int argc, char *argv[])
493 struct test_context ctx;
494 const char *test_file;
496 memset(&ctx, 0, sizeof ctx);
499 fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
503 if (argc >= 2 && !strcmp (argv[1], "-d")) {
511 test_file = "test.xml";
513 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
516 fprintf(stderr, "\n%d errors\n", ctx.errors);