src/test-driver.c
author James Bowes <jbowes@redhat.com>
Wed Jul 09 10:11:13 2008 -0400 (2008-07-09)
changeset 318 829d6711b316
parent 306 cd3954499086
child 339 159067260aad
permissions -rw-r--r--
Use strings to identify section types in the on-disk repo format.

Previously, a given razor file type had a fixed number of sections in a
fixed order, identified by an integer type. Now, sections are identified
by a named string (stored in a string pool after the section lists).

This will allow for razor files to contain arbitrary sections.

For bonus points, also drop the 4k section alignment and change the
magic byte string to "RZDB".

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