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