src/test-driver.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Apr 29 17:00:01 2009 +0100 (2009-04-29)
changeset 361 2523d03a840e
parent 307 95b6bcadd6c4
child 369 f8c27fe9fe63
permissions -rw-r--r--
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).
richard@300
     1
/*
richard@300
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
richard@300
     3
 * Copyright (C) 2008  Red Hat, Inc
richard@300
     4
 *
richard@300
     5
 * This program is free software; you can redistribute it and/or modify
richard@300
     6
 * it under the terms of the GNU General Public License as published by
richard@300
     7
 * the Free Software Foundation; either version 2 of the License, or
richard@300
     8
 * (at your option) any later version.
richard@300
     9
 *
richard@300
    10
 * This program is distributed in the hope that it will be useful,
richard@300
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
richard@300
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
richard@300
    13
 * GNU General Public License for more details.
richard@300
    14
 *
richard@300
    15
 * You should have received a copy of the GNU General Public License along
richard@300
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
richard@300
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
richard@300
    18
 */
richard@300
    19
rhughes@241
    20
#include <stdio.h>
rhughes@241
    21
#include <string.h>
rhughes@241
    22
#include <stdarg.h>
rhughes@241
    23
#include <unistd.h>
rhughes@241
    24
#include <fcntl.h>
rhughes@241
    25
#include <errno.h>
rhughes@241
    26
#include <expat.h>
rhughes@241
    27
rhughes@241
    28
#include "razor.h"
rhughes@241
    29
rhughes@241
    30
#define XML_BUFFER_SIZE 4096
rhughes@241
    31
rhughes@241
    32
static void
rhughes@241
    33
parse_xml_file(const char *filename,
rhughes@241
    34
	       XML_StartElementHandler start,
rhughes@241
    35
	       XML_EndElementHandler end,
rhughes@241
    36
	       void *data)
rhughes@241
    37
{
rhughes@241
    38
	XML_Parser parser;
rhughes@241
    39
	char *buffer;
rhughes@241
    40
	int fd, len, err;
rhughes@241
    41
rhughes@241
    42
	parser = XML_ParserCreate(NULL);
rhughes@241
    43
	XML_SetElementHandler(parser, start, end);
rhughes@241
    44
	XML_SetUserData(parser, data);
rhughes@241
    45
rhughes@241
    46
	fd = open(filename, O_RDONLY);
rhughes@241
    47
	if (fd < 0) {
ali@339
    48
		fprintf(stderr, "failed to open %s: %s\n", filename,
ali@339
    49
			strerror(errno));
rhughes@241
    50
		exit(-1);
rhughes@241
    51
	}
rhughes@241
    52
rhughes@241
    53
	while (1) {
rhughes@241
    54
		buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
rhughes@241
    55
		len = read(fd, buffer, XML_BUFFER_SIZE);
rhughes@241
    56
		if (len == 0)
rhughes@241
    57
			break;
rhughes@241
    58
		err = XML_ParseBuffer(parser, len, len == 0);
rhughes@241
    59
		if (err == XML_STATUS_ERROR) {
rhughes@241
    60
			fprintf(stderr, "parse error at line %lu:\n%s\n",
rhughes@241
    61
				XML_GetCurrentLineNumber(parser),
rhughes@241
    62
				XML_ErrorString(XML_GetErrorCode(parser)));
rhughes@241
    63
			exit(-1);
rhughes@241
    64
		}
rhughes@241
    65
	}
rhughes@241
    66
rhughes@241
    67
	if (fd < 0) {
ali@339
    68
		perror("read");
rhughes@241
    69
		exit(-1);
rhughes@241
    70
	}
rhughes@241
    71
rhughes@241
    72
	close(fd);
rhughes@241
    73
}
rhughes@241
    74
rhughes@241
    75
struct test_context {
rhughes@241
    76
	struct razor_set *system_set, *repo_set, *result_set;
rhughes@241
    77
rhughes@241
    78
	struct razor_importer *importer;
rhughes@241
    79
	struct razor_set **importer_set;
rhughes@241
    80
rhughes@241
    81
	struct razor_transaction *trans;
rhughes@241
    82
rhughes@241
    83
	char *install_pkgs[3], *remove_pkgs[3];
rhughes@241
    84
	int n_install_pkgs, n_remove_pkgs;
rhughes@241
    85
rhughes@241
    86
	int unsat;
rhughes@241
    87
	int in_result;
rhughes@241
    88
rhughes@241
    89
	int debug, errors;
rhughes@241
    90
};
rhughes@241
    91
rhughes@241
    92
static void
rhughes@241
    93
get_atts(const char **atts, ...)
rhughes@241
    94
{
rhughes@241
    95
	va_list ap;
rhughes@241
    96
	const char *name, **ptr;
rhughes@241
    97
	int i;
rhughes@241
    98
rhughes@241
    99
	va_start(ap, atts);
rhughes@241
   100
	while (name = va_arg(ap, const char *), name != NULL) {
rhughes@241
   101
		ptr = va_arg(ap, const char **);
rhughes@241
   102
		*ptr = NULL;
rhughes@241
   103
		for (i = 0; atts[i]; i += 2) {
rhughes@241
   104
			if (strcmp(atts[i], name) == 0)
rhughes@241
   105
				*ptr = atts[i + 1];
rhughes@241
   106
		}
rhughes@241
   107
	}
rhughes@241
   108
	va_end(ap);
rhughes@241
   109
}
rhughes@241
   110
jbowes@284
   111
static enum razor_property_flags
rhughes@241
   112
parse_relation (const char *rel_str)
rhughes@241
   113
{
rhughes@241
   114
	if (!rel_str)
rhughes@241
   115
		return -1;
rhughes@241
   116
	if (rel_str[0] == 'L')
jbowes@284
   117
		return rel_str[1] == 'E' ? RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_LESS;
rhughes@241
   118
	else if (rel_str[0] == 'G')
jbowes@284
   119
		return rel_str[1] == 'E' ? RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_GREATER;
rhughes@241
   120
	else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
jbowes@284
   121
		return RAZOR_PROPERTY_EQUAL;
rhughes@241
   122
	else
rhughes@241
   123
		return -1;
rhughes@241
   124
}
rhughes@241
   125
rhughes@241
   126
static void
rhughes@241
   127
start_test(struct test_context *ctx, const char **atts)
rhughes@241
   128
{
rhughes@241
   129
	const char *name = NULL;
rhughes@241
   130
rhughes@241
   131
	get_atts(atts, "name", &name, NULL);
rhughes@241
   132
	if (!name) {
rhughes@241
   133
		fprintf(stderr, "Test with no name\n");
rhughes@241
   134
		exit(1);
rhughes@241
   135
	}
rhughes@241
   136
	printf("%s\n", name);
rhughes@241
   137
}
rhughes@241
   138
rhughes@241
   139
static void
rhughes@241
   140
end_test(struct test_context *ctx)
rhughes@241
   141
{
rhughes@241
   142
	if (ctx->system_set) {
rhughes@241
   143
		razor_set_destroy(ctx->system_set);
rhughes@241
   144
		ctx->system_set = NULL;
rhughes@241
   145
	}
rhughes@241
   146
	if (ctx->repo_set) {
rhughes@241
   147
		razor_set_destroy(ctx->repo_set);
rhughes@241
   148
		ctx->repo_set = NULL;
rhughes@241
   149
	}
rhughes@241
   150
	if (ctx->result_set) {
rhughes@241
   151
		razor_set_destroy(ctx->result_set);
rhughes@241
   152
		ctx->result_set = NULL;
rhughes@241
   153
	}
rhughes@241
   154
	if (ctx->trans) {
rhughes@241
   155
		razor_transaction_destroy(ctx->trans);
rhughes@241
   156
		ctx->trans = NULL;
rhughes@241
   157
	}
rhughes@241
   158
}
rhughes@241
   159
rhughes@241
   160
static void
rhughes@241
   161
start_set(struct test_context *ctx, const char **atts)
rhughes@241
   162
{
rhughes@241
   163
	const char *name = NULL;
rhughes@241
   164
jbowes@284
   165
	ctx->importer = razor_importer_create();
rhughes@241
   166
	get_atts(atts, "name", &name, NULL);
rhughes@241
   167
	if (!name)
rhughes@241
   168
		ctx->importer_set = &ctx->result_set;
rhughes@241
   169
	else if (!strcmp(name, "system"))
rhughes@241
   170
		ctx->importer_set = &ctx->system_set;
rhughes@241
   171
	else if (!strcmp(name, "repo"))
rhughes@241
   172
		ctx->importer_set = &ctx->repo_set;
rhughes@241
   173
	else {
rhughes@241
   174
		fprintf(stderr, "  bad set name '%s'\n", name);
rhughes@241
   175
		exit(1);
rhughes@241
   176
	}
rhughes@241
   177
}
rhughes@241
   178
rhughes@241
   179
static void
rhughes@241
   180
end_set(struct test_context *ctx)
rhughes@241
   181
{
rhughes@241
   182
	*ctx->importer_set = razor_importer_finish(ctx->importer);
rhughes@241
   183
	ctx->importer = NULL;
rhughes@241
   184
}
rhughes@241
   185
rhughes@241
   186
static void
rhughes@241
   187
start_package(struct test_context *ctx, const char **atts)
rhughes@241
   188
{
rhughes@241
   189
	const char *name = NULL, *version = NULL, *arch = NULL;
rhughes@241
   190
rhughes@241
   191
	get_atts(atts, "name", &name,
rhughes@241
   192
		 "version", &version,
rhughes@241
   193
		 "arch", &arch,
rhughes@241
   194
		 NULL);
rhughes@241
   195
rhughes@241
   196
	if (!name) {
rhughes@241
   197
		fprintf(stderr, "  package with no name\n");
rhughes@241
   198
		exit(1);
rhughes@241
   199
	}
rhughes@241
   200
rhughes@241
   201
	razor_importer_begin_package(ctx->importer, name, version, arch);
rhughes@241
   202
	razor_importer_add_property(ctx->importer, name,
jbowes@284
   203
				    RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_PROVIDES,
jbowes@284
   204
				    version);
rhughes@241
   205
}
rhughes@241
   206
rhughes@241
   207
static void
rhughes@241
   208
end_package(struct test_context *ctx)
rhughes@241
   209
{
rhughes@241
   210
	razor_importer_finish_package(ctx->importer);
rhughes@241
   211
}
rhughes@241
   212
rhughes@241
   213
static void
jbowes@284
   214
add_property(struct test_context *ctx, enum razor_property_flags type, const char *name, enum razor_property_flags rel, const char *version)
rhughes@241
   215
{
rhughes@241
   216
	razor_importer_add_property(ctx->importer, name,
jbowes@284
   217
				    rel | type, version);
jbowes@284
   218
}
jbowes@284
   219
jbowes@284
   220
static const char*
jbowes@284
   221
razor_property_flags_relation_to_string(enum razor_property_flags rel)
jbowes@284
   222
{
jbowes@284
   223
	if (rel == RAZOR_PROPERTY_LESS)
jbowes@284
   224
		return "<";
jbowes@284
   225
	if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_LESS))
jbowes@284
   226
		return "<=";
jbowes@284
   227
	if (rel == RAZOR_PROPERTY_EQUAL)
jbowes@284
   228
		return "=";
jbowes@284
   229
	if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_GREATER))
jbowes@284
   230
		return ">=";
jbowes@284
   231
	if (rel == RAZOR_PROPERTY_GREATER)
jbowes@284
   232
		return ">";
jbowes@284
   233
jbowes@284
   234
	return "";
rhughes@241
   235
}
rhughes@241
   236
rhughes@241
   237
static void
rhughes@241
   238
check_unsatisfiable_property(struct test_context *ctx,
jbowes@284
   239
			     enum razor_property_flags type,
rhughes@241
   240
			     const char *name,
jbowes@284
   241
			     enum razor_property_flags rel,
rhughes@241
   242
			     const char *version)
rhughes@241
   243
{
rhughes@241
   244
	if (!version)
rhughes@241
   245
		version = "";
rhughes@241
   246
rhughes@241
   247
	if (razor_transaction_unsatisfied_property(ctx->trans,
jbowes@284
   248
						   name, rel | type, version))
rhughes@241
   249
		return;
rhughes@241
   250
rhughes@241
   251
	fprintf(stderr, "  didn't get unsatisfiable '%s %s %s'\n",
jbowes@284
   252
		name, razor_property_flags_relation_to_string(rel), version);
rhughes@241
   253
	ctx->errors++;
rhughes@241
   254
}
rhughes@241
   255
rhughes@241
   256
static void
jbowes@284
   257
start_property(struct test_context *ctx, enum razor_property_flags type, const char **atts)
rhughes@241
   258
{
rhughes@241
   259
	const char *name = NULL, *rel_str = NULL, *version = NULL;
jbowes@284
   260
	enum razor_property_flags rel;
rhughes@241
   261
rhughes@241
   262
	get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
rhughes@241
   263
	if (name == NULL) {
rhughes@241
   264
		fprintf(stderr, "  no name specified for property\n");
rhughes@241
   265
		exit(1);
rhughes@241
   266
	}
rhughes@241
   267
	if (version) {
rhughes@241
   268
		rel = parse_relation(rel_str);
rhughes@241
   269
		if (rel == -1) {
rhughes@241
   270
			fprintf(stderr, "  bad or missing version relation for property %s\n", name);
rhughes@241
   271
			exit(1);
rhughes@241
   272
		}
rhughes@241
   273
	} else
jbowes@284
   274
		rel = RAZOR_PROPERTY_EQUAL;
rhughes@241
   275
rhughes@241
   276
	if (ctx->unsat)
rhughes@241
   277
		check_unsatisfiable_property(ctx, type, name, rel, version);
rhughes@241
   278
	else
rhughes@241
   279
		add_property(ctx, type, name, rel, version);
rhughes@241
   280
}
rhughes@241
   281
rhughes@241
   282
static void
rhughes@241
   283
start_transaction(struct test_context *ctx, const char **atts)
rhughes@241
   284
{
rhughes@241
   285
	ctx->n_install_pkgs = 0;
rhughes@241
   286
	ctx->n_remove_pkgs = 0;
rhughes@241
   287
}
rhughes@241
   288
krh@306
   289
static struct razor_package *
krh@306
   290
get_package(struct razor_set *set, const char *package)
krh@306
   291
{
krh@306
   292
	struct razor_package_iterator *pi;
krh@306
   293
	struct razor_package *p;
krh@306
   294
	const char *name, *version, *arch;
krh@306
   295
krh@306
   296
	pi = razor_package_iterator_create(set);
richard@307
   297
	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_NAME, &name,
richard@307
   298
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   299
					   RAZOR_DETAIL_ARCH, &arch,
richard@307
   300
					   RAZOR_DETAIL_LAST)) {
krh@306
   301
		if (strcmp(package, name) == 0)
krh@306
   302
			break;
krh@306
   303
	}
krh@306
   304
	razor_package_iterator_destroy(pi);
krh@306
   305
krh@306
   306
	return p;
krh@306
   307
}
krh@306
   308
rhughes@241
   309
static void
rhughes@241
   310
end_transaction(struct test_context *ctx)
rhughes@241
   311
{
rhughes@241
   312
	struct razor_package *pkg;
rhughes@241
   313
	int errors, i;
rhughes@241
   314
rhughes@241
   315
	ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
rhughes@241
   316
	for (i = 0; i < ctx->n_install_pkgs; i++) {
krh@306
   317
		pkg = get_package(ctx->repo_set, ctx->install_pkgs[i]);
rhughes@241
   318
		razor_transaction_install_package(ctx->trans, pkg);
rhughes@241
   319
	}
rhughes@241
   320
	for (i = 0; i < ctx->n_remove_pkgs; i++) {
krh@306
   321
		pkg = get_package(ctx->system_set, ctx->remove_pkgs[i]);
jbowes@258
   322
		if (!pkg)
krh@306
   323
			pkg = get_package(ctx->repo_set, ctx->remove_pkgs[i]);
jbowes@258
   324
rhughes@241
   325
		razor_transaction_remove_package(ctx->trans, pkg);
rhughes@241
   326
	}
rhughes@241
   327
jbowes@284
   328
	razor_transaction_resolve(ctx->trans);
jbowes@284
   329
	errors = razor_transaction_describe(ctx->trans);
rhughes@241
   330
	printf("\n");
rhughes@241
   331
rhughes@241
   332
	while (ctx->n_install_pkgs--)
rhughes@241
   333
		free(ctx->install_pkgs[ctx->n_install_pkgs]);
rhughes@241
   334
	while (ctx->n_remove_pkgs--)
rhughes@241
   335
		free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
rhughes@241
   336
rhughes@241
   337
	if (!errors) {
rhughes@241
   338
		struct razor_set *new;
rhughes@241
   339
		new = razor_transaction_finish(ctx->trans);
jbowes@258
   340
		ctx->trans = NULL;
rhughes@241
   341
		ctx->system_set = new;
rhughes@241
   342
	}
rhughes@241
   343
}
rhughes@241
   344
rhughes@241
   345
static void
rhughes@241
   346
start_install_or_update(struct test_context *ctx, const char **atts)
rhughes@241
   347
{
rhughes@241
   348
	const char *name = NULL;
rhughes@241
   349
rhughes@241
   350
	get_atts(atts, "name", &name, NULL);
rhughes@241
   351
	if (!name) {
rhughes@241
   352
		fprintf(stderr, "  install/update with no name\n");
rhughes@241
   353
		exit(1);
rhughes@241
   354
	}
rhughes@241
   355
rhughes@241
   356
	ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
rhughes@241
   357
}
rhughes@241
   358
rhughes@241
   359
static void
rhughes@241
   360
start_remove(struct test_context *ctx, const char **atts)
rhughes@241
   361
{
rhughes@241
   362
	const char *name = NULL;
rhughes@241
   363
rhughes@241
   364
	get_atts(atts, "name", &name, NULL);
rhughes@241
   365
	if (!name) {
rhughes@241
   366
		fprintf(stderr, "  remove with no name\n");
rhughes@241
   367
		exit(1);
rhughes@241
   368
	}
rhughes@241
   369
rhughes@241
   370
	ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
rhughes@241
   371
}
rhughes@241
   372
rhughes@241
   373
static void
rhughes@241
   374
start_result(struct test_context *ctx, const char **atts)
rhughes@241
   375
{
rhughes@241
   376
	ctx->in_result = 1;
rhughes@241
   377
}
rhughes@241
   378
rhughes@241
   379
static void
jbowes@284
   380
diff_callback(enum razor_diff_action action,
jbowes@284
   381
	      struct razor_package *package,
jbowes@284
   382
	      const char *name,
jbowes@284
   383
	      const char *version,
rhughes@241
   384
	      const char *arch,
rhughes@241
   385
	      void *data)
rhughes@241
   386
{
rhughes@241
   387
	struct test_context *ctx = data;
rhughes@241
   388
rhughes@241
   389
	ctx->errors++;
jbowes@284
   390
	if (action == RAZOR_DIFF_ACTION_REMOVE) {
rhughes@241
   391
		fprintf(stderr, "  result set should not contain %s %s\n",
jbowes@284
   392
			name, version);
rhughes@241
   393
	} else {
rhughes@241
   394
		fprintf(stderr, "  result set should contain %s %s\n",
jbowes@284
   395
			name, version);
rhughes@241
   396
	}
rhughes@241
   397
}
rhughes@241
   398
rhughes@241
   399
static void
rhughes@241
   400
end_result(struct test_context *ctx)
rhughes@241
   401
{
rhughes@241
   402
	ctx->in_result = 0;
rhughes@241
   403
rhughes@241
   404
	if (ctx->result_set) {
rhughes@241
   405
		if (!ctx->system_set)
rhughes@241
   406
			ctx->system_set = razor_set_create();
rhughes@241
   407
		razor_set_diff(ctx->system_set, ctx->result_set,
rhughes@241
   408
			       diff_callback, ctx);
rhughes@241
   409
	}
rhughes@241
   410
}
rhughes@241
   411
rhughes@241
   412
static void
rhughes@241
   413
start_unsatisfiable(struct test_context *ctx, const char **atts)
rhughes@241
   414
{
rhughes@241
   415
	if (ctx->result_set) {
rhughes@241
   416
		fprintf(stderr, "Expected to fail, but didn't\n");
rhughes@241
   417
		exit(1);
rhughes@241
   418
	}
rhughes@241
   419
rhughes@241
   420
	ctx->unsat = 1;
rhughes@241
   421
}
rhughes@241
   422
rhughes@241
   423
static void
rhughes@241
   424
end_unsatisfiable(struct test_context *ctx)
rhughes@241
   425
{
rhughes@241
   426
	ctx->unsat = 0;
rhughes@241
   427
}
rhughes@241
   428
rhughes@241
   429
static void
rhughes@241
   430
start_test_element(void *data, const char *element, const char **atts)
rhughes@241
   431
{
rhughes@241
   432
	struct test_context *ctx = data;
rhughes@241
   433
rhughes@241
   434
	if (strcmp(element, "tests") == 0) {
rhughes@241
   435
		;
rhughes@241
   436
	} else if (strcmp(element, "test") == 0) {
rhughes@241
   437
		start_test(ctx, atts);
rhughes@241
   438
	} else if (strcmp(element, "set") == 0) {
rhughes@241
   439
		start_set(ctx, atts);
rhughes@241
   440
	} else if (strcmp(element, "transaction") == 0) {
rhughes@241
   441
		start_transaction(ctx, atts);
rhughes@241
   442
	} else if (strcmp(element, "install") == 0) {
rhughes@241
   443
		start_install_or_update(ctx, atts);
rhughes@241
   444
	} else if (strcmp(element, "install") == 0) {
rhughes@241
   445
		start_install_or_update(ctx, atts);
rhughes@241
   446
	} else if (strcmp(element, "remove") == 0) {
rhughes@241
   447
		start_remove(ctx, atts);
rhughes@241
   448
	} else if (strcmp(element, "result") == 0) {
rhughes@241
   449
		start_result(ctx, atts);
rhughes@241
   450
	} else if (strcmp(element, "unsatisfiable") == 0) {
rhughes@241
   451
		start_unsatisfiable(ctx, atts);
rhughes@241
   452
	} else if (strcmp(element, "package") == 0) {
rhughes@241
   453
		start_package(ctx, atts);
rhughes@241
   454
	} else if (strcmp(element, "requires") == 0) {
rhughes@241
   455
		start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
rhughes@241
   456
	} else if (strcmp(element, "provides") == 0) {
rhughes@241
   457
		start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
rhughes@241
   458
	} else if (strcmp(element, "conflicts") == 0) {
rhughes@241
   459
		start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
rhughes@241
   460
	} else if (strcmp(element, "obsoletes") == 0) {
rhughes@241
   461
		start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
rhughes@241
   462
	} else {
rhughes@241
   463
		fprintf(stderr, "Unrecognized element '%s'\n", element);
rhughes@241
   464
		exit(1);
rhughes@241
   465
	}
rhughes@241
   466
}
rhughes@241
   467
rhughes@241
   468
static void
rhughes@241
   469
end_test_element (void *data, const char *element)
rhughes@241
   470
{
rhughes@241
   471
	struct test_context *ctx = data;
rhughes@241
   472
rhughes@241
   473
	if (strcmp(element, "test") == 0) {
rhughes@241
   474
		end_test(ctx);
rhughes@241
   475
	} else if (strcmp(element, "set") == 0) {
rhughes@241
   476
		end_set(ctx);
rhughes@241
   477
	} else if (strcmp(element, "package") == 0) {
rhughes@241
   478
		end_package(ctx);
rhughes@241
   479
	} else if (strcmp(element, "transaction") == 0) {
rhughes@241
   480
		end_transaction(ctx);
rhughes@241
   481
	} else if (strcmp(element, "result") == 0) {
rhughes@241
   482
		end_result(ctx);
rhughes@241
   483
	} else if (strcmp(element, "unsatisfiable") == 0) {
rhughes@241
   484
		end_unsatisfiable(ctx);
rhughes@241
   485
	}
rhughes@241
   486
}
rhughes@241
   487
rhughes@241
   488
int main(int argc, char *argv[])
rhughes@241
   489
{
rhughes@241
   490
	struct test_context ctx;
rhughes@241
   491
	const char *test_file;
rhughes@241
   492
rhughes@241
   493
	memset(&ctx, 0, sizeof ctx);
rhughes@241
   494
rhughes@241
   495
	if (argc > 3) {
rhughes@241
   496
		fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
rhughes@241
   497
		exit(-1);
rhughes@241
   498
	}
rhughes@241
   499
rhughes@241
   500
	if (argc >= 2 && !strcmp (argv[1], "-d")) {
rhughes@241
   501
		ctx.debug = 1;
rhughes@241
   502
		argc--;
rhughes@241
   503
		argv++;
rhughes@241
   504
	}
rhughes@241
   505
	if (argc == 2)
rhughes@241
   506
		test_file = argv[1];
rhughes@241
   507
	else
rhughes@241
   508
		test_file = "test.xml";
rhughes@241
   509
rhughes@241
   510
	parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
rhughes@241
   511
rhughes@241
   512
	if (ctx.errors) {
rhughes@241
   513
		fprintf(stderr, "\n%d errors\n", ctx.errors);
rhughes@241
   514
		return 1;
rhughes@241
   515
	} else
rhughes@241
   516
		return 0;
rhughes@241
   517
}