Add iterator API, boot-strap test suite.
authorKristian H?gsberg <krh@redhat.com>
Thu Jan 03 19:50:20 2008 -0500 (2008-01-03)
changeset 9274f19848a71b
parent 91 6884cefd1b8c
child 93 f173765f7623
Add iterator API, boot-strap test suite.
Makefile
main.c
razor.c
razor.h
sets.xml
test-driver.c
     1.1 --- a/Makefile	Thu Jan 03 09:32:31 2008 -0500
     1.2 +++ b/Makefile	Thu Jan 03 19:50:20 2008 -0500
     1.3 @@ -8,7 +8,7 @@
     1.4  test-driver : razor.o util.o test-driver.o
     1.5  
     1.6  test : test-driver
     1.7 -	./test-driver sets.xml test.xml
     1.8 +	./test-driver test.xml
     1.9  
    1.10  clean :
    1.11  	rm -f *.o razor
     2.1 --- a/main.c	Thu Jan 03 09:32:31 2008 -0500
     2.2 +++ b/main.c	Thu Jan 03 19:50:20 2008 -0500
     2.3 @@ -17,9 +17,53 @@
     2.4  command_list(int argc, const char *argv[])
     2.5  {
     2.6  	struct razor_set *set;
     2.7 +	struct razor_package_iterator *pi;
     2.8 +	struct razor_package *package;
     2.9 +	const char *pattern = argv[0], *name, *version;
    2.10  
    2.11  	set = razor_set_open(repo_filename);
    2.12 -	razor_set_list(set, argv[0]);
    2.13 +	pi = razor_package_iterator_create(set);
    2.14 +	while (razor_package_iterator_next(pi, &package, &name, &version)) {
    2.15 +		if (pattern && fnmatch(pattern, name, 0) != 0)
    2.16 +			continue;
    2.17 +
    2.18 +		printf("%s-%s\n", name, version);
    2.19 +	}
    2.20 +	razor_package_iterator_destroy(pi);
    2.21 +	razor_set_destroy(set);
    2.22 +
    2.23 +	return 0;
    2.24 +}
    2.25 +
    2.26 +static int
    2.27 +list_properties(const char *package_name,
    2.28 +		enum razor_property_type required_type)
    2.29 +{
    2.30 +	struct razor_set *set;
    2.31 +	struct razor_property *property;
    2.32 +	struct razor_package *package;
    2.33 +	struct razor_property_iterator *pi;
    2.34 +	const char *name, *version;
    2.35 +	enum razor_property_type type;
    2.36 +
    2.37 +	set = razor_set_open(repo_filename);
    2.38 +	if (package_name)
    2.39 +		package = razor_set_get_package(set, package_name);
    2.40 +	else
    2.41 +		package = NULL;
    2.42 +
    2.43 +	pi = razor_property_iterator_create(set, package);
    2.44 +	while (razor_property_iterator_next(pi, &property,
    2.45 +					    &name, &version, &type)) {
    2.46 +		if (type != required_type)
    2.47 +			continue;
    2.48 +		if (version[0] == '\0')
    2.49 +			printf("%s\n", name);
    2.50 +		else
    2.51 +			printf("%s-%s\n", name, version);
    2.52 +	}
    2.53 +	razor_property_iterator_destroy(pi);
    2.54 +
    2.55  	razor_set_destroy(set);
    2.56  
    2.57  	return 0;
    2.58 @@ -28,49 +72,25 @@
    2.59  static int
    2.60  command_list_requires(int argc, const char *argv[])
    2.61  {
    2.62 -	struct razor_set *set;
    2.63 -
    2.64 -	set = razor_set_open(repo_filename);
    2.65 -	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_REQUIRES);
    2.66 -	razor_set_destroy(set);
    2.67 -
    2.68 -	return 0;
    2.69 +	return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
    2.70  }
    2.71  
    2.72  static int
    2.73  command_list_provides(int argc, const char *argv[])
    2.74  {
    2.75 -	struct razor_set *set;
    2.76 -
    2.77 -	set = razor_set_open(repo_filename);
    2.78 -	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_PROVIDES);
    2.79 -	razor_set_destroy(set);
    2.80 -
    2.81 -	return 0;
    2.82 +	return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
    2.83  }
    2.84  
    2.85  static int
    2.86  command_list_obsoletes(int argc, const char *argv[])
    2.87  {
    2.88 -	struct razor_set *set;
    2.89 -
    2.90 -	set = razor_set_open(repo_filename);
    2.91 -	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_OBSOLETES);
    2.92 -	razor_set_destroy(set);
    2.93 -
    2.94 -	return 0;
    2.95 +	return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
    2.96  }
    2.97  
    2.98  static int
    2.99  command_list_conflicts(int argc, const char *argv[])
   2.100  {
   2.101 -	struct razor_set *set;
   2.102 -
   2.103 -	set = razor_set_open(repo_filename);
   2.104 -	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_CONFLICTS);
   2.105 -	razor_set_destroy(set);
   2.106 -
   2.107 -	return 0;
   2.108 +	return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
   2.109  }
   2.110  
   2.111  static int
     3.1 --- a/razor.c	Thu Jan 03 09:32:31 2008 -0500
     3.2 +++ b/razor.c	Thu Jan 03 19:50:20 2008 -0500
     3.3 @@ -323,7 +323,12 @@
     3.4  static unsigned long
     3.5  add_to_property_pool(struct array *pool, struct array *properties)
     3.6  {
     3.7 -	unsigned long  *p;
     3.8 +	unsigned long *p;
     3.9 +
    3.10 +	if (properties->size == 0)
    3.11 +		return ~0;
    3.12 +	else if (properties->size == sizeof *p)
    3.13 +		return *(unsigned long *) properties->data | RAZOR_IMMEDIATE;
    3.14  
    3.15  	p = array_add(pool, properties->size);
    3.16  	memcpy(p, properties->data, properties->size);
    3.17 @@ -756,9 +761,7 @@
    3.18  		s += p->count;
    3.19  
    3.20  		if (p->packages.size == 0) {
    3.21 -			/* FIXME: We need to make sure this is handled
    3.22 -			 * correctly as the empty list. */
    3.23 -			e->packages = 0 | RAZOR_IMMEDIATE;
    3.24 +			e->packages = ~0;
    3.25  		} else if (p->packages.size / sizeof *r == 1) {
    3.26  			r = p->packages.data;
    3.27  			e->packages = *r | RAZOR_IMMEDIATE;
    3.28 @@ -855,7 +858,7 @@
    3.29  	e = array_add(&importer->set->files, sizeof *e);
    3.30  	e->name = root.name | RAZOR_ENTRY_LAST;
    3.31  	e->start = 1;
    3.32 -	e->packages = 0;
    3.33 +	e->packages = ~0;
    3.34  
    3.35  	serialize_files(importer->set, &root, &importer->set->files);
    3.36  
    3.37 @@ -874,10 +877,11 @@
    3.38  	count = set->packages.size / sizeof *p;
    3.39  	pkgs = zalloc(count * sizeof *pkgs);
    3.40  
    3.41 -	e = set->files.data;
    3.42  	end = set->files.data + set->files.size;
    3.43 -	while (e < end) {
    3.44 -		if (e->packages & RAZOR_IMMEDIATE) {
    3.45 +	for (e = set->files.data; e < end; e++) {
    3.46 +		if (e->packages == ~0) {
    3.47 +			continue;
    3.48 +		} else if (e->packages & RAZOR_IMMEDIATE) {
    3.49  			e->packages = rmap[e->packages & RAZOR_ENTRY_MASK] |
    3.50  				RAZOR_IMMEDIATE;
    3.51  			r = &e->packages;
    3.52 @@ -891,7 +895,6 @@
    3.53  			if (*r++ & RAZOR_IMMEDIATE)
    3.54  				break;
    3.55  		}
    3.56 -		e++;
    3.57  	}
    3.58  
    3.59  	packages = set->packages.data;
    3.60 @@ -939,23 +942,43 @@
    3.61  	return set;
    3.62  }
    3.63  
    3.64 -void
    3.65 -razor_set_list(struct razor_set *set, const char *pattern)
    3.66 +struct razor_package_iterator {
    3.67 +	struct razor_set *set;
    3.68 +	struct razor_package *package, *end;
    3.69 +};
    3.70 +
    3.71 +struct razor_package_iterator *
    3.72 +razor_package_iterator_create(struct razor_set *set)
    3.73  {
    3.74 -	struct razor_package *p, *end;
    3.75 -	int with_version = 0;
    3.76 +	struct razor_package_iterator *pi;
    3.77 +
    3.78 +	pi = zalloc(sizeof *pi);
    3.79 +	pi->set = set;
    3.80 +	pi->package = set->packages.data;
    3.81 +	pi->end = set->packages.data + set->packages.size;
    3.82 +
    3.83 +	return pi;
    3.84 +}
    3.85 +
    3.86 +int
    3.87 +razor_package_iterator_next(struct razor_package_iterator *pi,
    3.88 +			    struct razor_package **package,
    3.89 +			    const char **name, const char **version)
    3.90 +{
    3.91  	char *pool;
    3.92  
    3.93 -	pool = set->string_pool.data;
    3.94 -	end = set->packages.data + set->packages.size;
    3.95 -	for (p = set->packages.data; p < end; p++) {
    3.96 -		if (pattern && fnmatch(pattern, &pool[p->name], 0) != 0)
    3.97 -		    continue;
    3.98 -		if (with_version)
    3.99 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   3.100 -		else
   3.101 -			printf("%s\n", &pool[p->name]);
   3.102 -	}
   3.103 +	pool = pi->set->string_pool.data;
   3.104 +	*package = pi->package;
   3.105 +	*name = &pool[pi->package->name];
   3.106 +	*version = &pool[pi->package->version];
   3.107 +
   3.108 +	return pi->package++ < pi->end;
   3.109 +}
   3.110 +
   3.111 +void
   3.112 +razor_package_iterator_destroy(struct razor_package_iterator *pi)
   3.113 +{
   3.114 +	free(pi);
   3.115  }
   3.116  
   3.117  struct razor_set *bsearch_set;
   3.118 @@ -1010,51 +1033,71 @@
   3.119  	return p;
   3.120  }
   3.121  
   3.122 +struct razor_property_iterator {
   3.123 +	struct razor_set *set;
   3.124 +	struct razor_property *property, *end;
   3.125 +	unsigned long *index;
   3.126 +	int last;
   3.127 +};
   3.128 +
   3.129 +struct razor_property_iterator *
   3.130 +razor_property_iterator_create(struct razor_set *set,
   3.131 +			       struct razor_package *package)
   3.132 +{
   3.133 +	struct razor_property_iterator *pi;
   3.134 +
   3.135 +	pi = zalloc(sizeof *pi);
   3.136 +	pi->set = set;
   3.137 +	pi->property = set->properties.data;
   3.138 +	pi->end = set->properties.data + set->properties.size;
   3.139 +	if (package) {
   3.140 +		pi->index = (unsigned long *)
   3.141 +			set->property_pool.data + package->properties;
   3.142 +		pi->last = 0;
   3.143 +	} else {
   3.144 +		pi->index = NULL;
   3.145 +		pi->last = 0;
   3.146 +	}
   3.147 +
   3.148 +	return pi;
   3.149 +}
   3.150 +
   3.151 +int
   3.152 +razor_property_iterator_next(struct razor_property_iterator *pi,
   3.153 +			     struct razor_property **property,
   3.154 +			     const char **name, const char **version,
   3.155 +			     enum razor_property_type *type)
   3.156 +{
   3.157 +	char *pool;
   3.158 +	unsigned long flags, index;
   3.159 +	int valid;
   3.160 +	struct razor_property *p, *properties;
   3.161 +
   3.162 +	if (pi->index) {
   3.163 +		properties = pi->set->properties.data;
   3.164 +		p = &properties[*pi->index & RAZOR_ENTRY_MASK];
   3.165 +		valid = !pi->last;
   3.166 +		pi->last = (*pi->index++ & RAZOR_IMMEDIATE) != 0;
   3.167 +		if (!valid)
   3.168 +			return valid;
   3.169 +	} else {
   3.170 +		p = pi->property++;
   3.171 +		valid = p < pi->end;
   3.172 +	}			
   3.173 +
   3.174 +	pool = pi->set->string_pool.data;
   3.175 +	*property = p;
   3.176 +	*name = &pool[p->name & RAZOR_ENTRY_MASK];
   3.177 +	*version = &pool[p->version];
   3.178 +	*type = p->name >> 30;
   3.179 +
   3.180 +	return valid;
   3.181 +}
   3.182 +
   3.183  void
   3.184 -razor_set_list_properties(struct razor_set *set, const char *name,
   3.185 -			  enum razor_property_type type)
   3.186 +razor_property_iterator_destroy(struct razor_property_iterator *pi)
   3.187  {
   3.188 -	struct razor_property *p, *properties, *end;
   3.189 -	struct razor_package *package;
   3.190 -	unsigned long *r;
   3.191 -	char *pool;
   3.192 -
   3.193 -	pool = set->string_pool.data;
   3.194 -
   3.195 -	if (name) {
   3.196 -		package = razor_set_get_package(set, name);
   3.197 -		r = (unsigned long *) set->property_pool.data +
   3.198 -			package->properties;
   3.199 -		properties = set->properties.data;
   3.200 -		while (1) {
   3.201 -			p = &properties[*r & RAZOR_ENTRY_MASK];
   3.202 -			if ((p->name >> 30) != type)
   3.203 -				goto next;
   3.204 -			if (pool[p->version] == '\0')
   3.205 -				printf("%s\n",
   3.206 -				       &pool[p->name & RAZOR_ENTRY_MASK]);
   3.207 -			else
   3.208 -				printf("%s-%s\n",
   3.209 -				       &pool[p->name & RAZOR_ENTRY_MASK],
   3.210 -				       &pool[p->version]);
   3.211 -		next:
   3.212 -			if (*r++ & RAZOR_IMMEDIATE)
   3.213 -				break;
   3.214 -		}
   3.215 -	} else {
   3.216 -		end = set->properties.data + set->properties.size;
   3.217 -		for (p = set->properties.data; p < end; p++) {
   3.218 -			if ((p->name >> 30) != type)
   3.219 -				continue;
   3.220 -			if (pool[p->version] == '\0')
   3.221 -				printf("%s\n",
   3.222 -				       &pool[p->name & RAZOR_ENTRY_MASK]);
   3.223 -			else
   3.224 -				printf("%s-%s\n",
   3.225 -				       &pool[p->name & RAZOR_ENTRY_MASK],
   3.226 -				       &pool[p->version]);
   3.227 -		}
   3.228 -	}
   3.229 +	free(pi);
   3.230  }
   3.231  
   3.232  void
     4.1 --- a/razor.h	Thu Jan 03 09:32:31 2008 -0500
     4.2 +++ b/razor.h	Thu Jan 03 19:50:20 2008 -0500
     4.3 @@ -4,6 +4,8 @@
     4.4  #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     4.5  
     4.6  struct razor_set;
     4.7 +struct razor_package;
     4.8 +struct razor_property;
     4.9  
    4.10  enum razor_property_type {
    4.11  	RAZOR_PROPERTY_REQUIRES,
    4.12 @@ -17,7 +19,33 @@
    4.13  void razor_set_destroy(struct razor_set *set);
    4.14  int razor_set_write(struct razor_set *set, const char *filename);
    4.15  
    4.16 -void razor_set_list(struct razor_set *set, const char *pattern);
    4.17 +struct razor_package *
    4.18 +razor_set_get_package(struct razor_set *set, const char *package);
    4.19 +
    4.20 +struct razor_property *
    4.21 +razor_set_get_property(struct razor_set *set, const char *property);
    4.22 +
    4.23 +struct razor_package_iterator;
    4.24 +struct razor_package_iterator *
    4.25 +razor_package_iterator_create(struct razor_set *set);
    4.26 +
    4.27 +int razor_package_iterator_next(struct razor_package_iterator *pi,
    4.28 +				struct razor_package **package,
    4.29 +				const char **name, const char **version);
    4.30 +void razor_package_iterator_destroy(struct razor_package_iterator *pi);
    4.31 +
    4.32 +struct razor_property_iterator;
    4.33 +struct razor_property_iterator *
    4.34 +razor_property_iterator_create(struct razor_set *set,
    4.35 +			       struct razor_package *package);
    4.36 +int razor_property_iterator_next(struct razor_property_iterator *pi,
    4.37 +				 struct razor_property **property,
    4.38 +				 const char **name, const char **version,
    4.39 +				 enum razor_property_type *type);
    4.40 +void
    4.41 +razor_property_iterator_destroy(struct razor_property_iterator *pi);
    4.42 +
    4.43 +
    4.44  void razor_set_list_properties(struct razor_set *set, const char *name,
    4.45  			       enum razor_property_type type);
    4.46  void razor_set_list_property_packages(struct razor_set *set,
     5.1 --- a/sets.xml	Thu Jan 03 09:32:31 2008 -0500
     5.2 +++ b/sets.xml	Thu Jan 03 19:50:20 2008 -0500
     5.3 @@ -1,4 +1,5 @@
     5.4  <test-sets>
     5.5 +
     5.6    <set name="b">
     5.7      <package name="bash" version="3.2-18.fc8">
     5.8        <requires name="libc.so.6"/>
     5.9 @@ -8,4 +9,16 @@
    5.10        <file name="/bin/bash"/>
    5.11      </package>
    5.12    </set>
    5.13 +
    5.14 +  <set name="c">
    5.15 +    <package name="nss" version="1.8-fc10">
    5.16 +      <provides name="nss" eq="1.8-fc10"/>
    5.17 +      <file name="/bin/nss"/>
    5.18 +    </package>
    5.19 +
    5.20 +    <package name="x" version="2">
    5.21 +      <conflicts name="y" eq="1.1"/>
    5.22 +    </package>
    5.23 +  </set>
    5.24 +
    5.25  </test-sets>
     6.1 --- a/test-driver.c	Thu Jan 03 09:32:31 2008 -0500
     6.2 +++ b/test-driver.c	Thu Jan 03 19:50:20 2008 -0500
     6.3 @@ -28,7 +28,7 @@
     6.4  
     6.5  	fd = open(filename, O_RDONLY);
     6.6  	if (fd < 0) {
     6.7 -		fprintf(stderr, "open: %m\n");
     6.8 +		fprintf(stderr, "failed to open %s: %m\n", filename);
     6.9  		exit(-1);
    6.10  	}
    6.11  
    6.12 @@ -59,6 +59,8 @@
    6.13  struct test_context {
    6.14  	struct razor_importer *importer;
    6.15  	struct test_set *sets;
    6.16 +	struct razor_package_iterator *package_iterator;
    6.17 +	struct razor_property_iterator *property_iterator;
    6.18  };
    6.19  
    6.20  static void
    6.21 @@ -71,6 +73,7 @@
    6.22  	va_start(ap, atts);
    6.23  	while (name = va_arg(ap, const char *), name != NULL) {
    6.24  		ptr = va_arg(ap, const char **);
    6.25 +		*ptr = NULL;
    6.26  		for (i = 0; atts[i]; i += 2) {
    6.27  			if (strcmp(atts[i], name) == 0)
    6.28  				*ptr = atts[i + 1];
    6.29 @@ -84,14 +87,8 @@
    6.30  	       enum razor_property_type type)
    6.31  {
    6.32  	const char *name = NULL, *version = NULL;
    6.33 -	int i;
    6.34  
    6.35 -	for (i = 0; atts[i]; i += 2) {
    6.36 -		if (strcmp(atts[i], "name") == 0)
    6.37 -			name = atts[i + 1];
    6.38 -		else if (strcmp(atts[i], "eq") == 0)
    6.39 -			version = atts[i + 1];
    6.40 -	}
    6.41 +	get_atts(atts, "name", &name, "eq", &version, NULL);
    6.42  
    6.43  	if (name == NULL) {
    6.44  		fprintf(stderr, "no name specified for property\n");
    6.45 @@ -102,7 +99,7 @@
    6.46  }
    6.47  
    6.48  static void
    6.49 -start_test_sets_element(void *data, const char *element, const char **atts)
    6.50 +start_set_element(void *data, const char *element, const char **atts)
    6.51  {
    6.52  	struct test_context *ctx = data;
    6.53  	struct test_set *set;
    6.54 @@ -136,7 +133,7 @@
    6.55  }
    6.56  
    6.57  static void
    6.58 -end_test_sets_element (void *data, const char *name)
    6.59 +end_set_element (void *data, const char *name)
    6.60  {
    6.61  	struct test_context *ctx = data;
    6.62  
    6.63 @@ -147,24 +144,193 @@
    6.64  	}
    6.65  }
    6.66  
    6.67 +static struct razor_set *
    6.68 +lookup_set(struct test_context *ctx, const char *name)
    6.69 +{
    6.70 +	struct test_set *set;
    6.71 +
    6.72 +	for (set = ctx->sets; set != NULL; set = set->next) {
    6.73 +		if (strcmp(set->name, name) == 0)
    6.74 +			return set->set;
    6.75 +	}
    6.76 +
    6.77 +	return NULL;
    6.78 +}
    6.79 +
    6.80 +static void
    6.81 +verify_begin(struct test_context *ctx, const char **atts)
    6.82 +{
    6.83 +	struct razor_set *set;
    6.84 +	const char *type, *name;
    6.85 +
    6.86 +	get_atts(atts, "type", &type, "set", &name, NULL);
    6.87 +	set = lookup_set(ctx, name);
    6.88 +	if (set == NULL) {
    6.89 +		fprintf(stderr, "set %s not found\n", name);
    6.90 +		exit(-1);
    6.91 +	}
    6.92 +
    6.93 +	if (strcmp(type, "packages") == 0) {
    6.94 +		ctx->package_iterator =
    6.95 +			razor_package_iterator_create(set);
    6.96 +	} else if (strcmp(type, "properties") == 0) {
    6.97 +		ctx->property_iterator =
    6.98 +			razor_property_iterator_create(set, NULL);
    6.99 +	} else {
   6.100 +		fprintf(stderr,
   6.101 +			"unknown compare type \"%s\"\n", type);
   6.102 +		exit(-1);
   6.103 +	}
   6.104 +}
   6.105 +
   6.106 +static void
   6.107 +verify_end(struct test_context *ctx)
   6.108 +{
   6.109 +	struct razor_package *package;
   6.110 +	struct razor_property *property;
   6.111 +	const char *name, *version, *ref_name, *ref_version;
   6.112 +	enum razor_property_type type;
   6.113 +
   6.114 +	if (ctx->package_iterator != NULL) {
   6.115 +		if (razor_package_iterator_next(ctx->package_iterator,
   6.116 +						&package,
   6.117 +						&name, &version)) {
   6.118 +			fprintf(stderr, "too few packages in set\n");
   6.119 +			exit(-1);
   6.120 +		}
   6.121 +				
   6.122 +		razor_package_iterator_destroy(ctx->package_iterator);
   6.123 +		ctx->package_iterator = NULL;
   6.124 +	}
   6.125 +
   6.126 +	if (ctx->property_iterator != NULL) {
   6.127 +		if (razor_property_iterator_next(ctx->property_iterator,
   6.128 +						 &property,
   6.129 +						 &name, &version, &type)) {
   6.130 +			fprintf(stderr, "too few properties in set\n");
   6.131 +			exit(-1);
   6.132 +		}
   6.133 +
   6.134 +		razor_property_iterator_destroy(ctx->property_iterator);
   6.135 +		ctx->property_iterator = NULL;
   6.136 +	}
   6.137 +}
   6.138 +
   6.139 +static void
   6.140 +verify_package(struct test_context *ctx, const char **atts)
   6.141 +{
   6.142 +	struct razor_package *package;
   6.143 +	const char *name, *version, *ref_name, *ref_version;
   6.144 +
   6.145 +	if (ctx->package_iterator == NULL) {
   6.146 +		fprintf(stderr,
   6.147 +			"\"package\" element seen, "
   6.148 +			"but not in package verify mode\n");
   6.149 +		exit(-1);
   6.150 +	}
   6.151 +
   6.152 +	get_atts(atts, "name", &ref_name, "version", &ref_version, NULL);
   6.153 +	if (!razor_package_iterator_next(ctx->package_iterator,
   6.154 +					 &package, &name, &version)) {
   6.155 +		fprintf(stderr, "too many packages in set\n");
   6.156 +		exit(-1);
   6.157 +	}
   6.158 +			
   6.159 +	if (strcmp(name, ref_name) != 0 || strcmp(version, ref_version) != 0) {
   6.160 +		fprintf(stderr,
   6.161 +			"package mismatch; expected %s-%s, got %s-%s\n",
   6.162 +			ref_name, ref_version, name, version);
   6.163 +		exit(-1);
   6.164 +	}
   6.165 +}
   6.166 +
   6.167 +static void
   6.168 +verify_property(struct test_context *ctx,
   6.169 +		enum razor_property_type ref_type, const char **atts)
   6.170 +{
   6.171 +	struct razor_property *property;
   6.172 +	const char *name, *version, *ref_name, *ref_version;
   6.173 +	enum razor_property_type type;
   6.174 +	int same_version;
   6.175 +
   6.176 +	if (ctx->property_iterator == NULL) {
   6.177 +		fprintf(stderr,
   6.178 +			"\"requires/provides\" element seen, "
   6.179 +			"but not in property verify mode\n");
   6.180 +		exit(-1);
   6.181 +	}
   6.182 +
   6.183 +	get_atts(atts, "name", &ref_name, "eq", &ref_version, NULL);
   6.184 +	if (!razor_property_iterator_next(ctx->property_iterator, &property,
   6.185 +					  &name, &version, &type)) {
   6.186 +		fprintf(stderr, "too many properties in set\n");
   6.187 +		exit(-1);
   6.188 +	}
   6.189 +			
   6.190 +	if (version != NULL && ref_version != NULL)
   6.191 +		same_version = strcmp(version, ref_version) == 0;
   6.192 +	else if (version == NULL && ref_version == NULL)
   6.193 +		same_version = 1;
   6.194 +	else
   6.195 +		same_version = 0;
   6.196 +
   6.197 +	if (strcmp(name, ref_name) != 0 || !same_version || type != ref_type) {
   6.198 +		fprintf(stderr,
   6.199 +			"property mismatch; expected %s-%s/%d, got %s-%s/%d\n",
   6.200 +			ref_name, ref_version, ref_type,
   6.201 +			name, version, type);
   6.202 +		exit(-1);
   6.203 +	}
   6.204 +}
   6.205 +
   6.206 +static void
   6.207 +start_test_element(void *data, const char *element, const char **atts)
   6.208 +{
   6.209 +	struct test_context *ctx = data;
   6.210 +	struct razor_set *set;
   6.211 +	const char *name;
   6.212 +
   6.213 +	if (strcmp(element, "import") == 0) {
   6.214 +		get_atts(atts, "file", &name, NULL);
   6.215 +		parse_xml_file(name, start_set_element, end_set_element, ctx);
   6.216 +	} else if (strcmp(element, "update") == 0) {
   6.217 +		/* run update to create new set */
   6.218 +	} else if (strcmp(element, "verify") == 0) {
   6.219 +		verify_begin(ctx, atts);
   6.220 +	} else if (strcmp(element, "package") == 0) {
   6.221 +		verify_package(ctx, atts);
   6.222 +	} else if (strcmp(element, "requires") == 0) {
   6.223 +		verify_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
   6.224 +	} else if (strcmp(element, "provides") == 0) {
   6.225 +		verify_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
   6.226 +	} else if (strcmp(element, "conflicts") == 0) {
   6.227 +		verify_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
   6.228 +	} else if (strcmp(element, "obsoletes") == 0) {
   6.229 +		verify_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
   6.230 +	}
   6.231 +}
   6.232 +
   6.233 +static void
   6.234 +end_test_element (void *data, const char *element)
   6.235 +{
   6.236 +	struct test_context *ctx = data;
   6.237 +
   6.238 +	if (strcmp(element, "verify") == 0)
   6.239 +		verify_end(ctx);
   6.240 +}
   6.241 +
   6.242  int main(int argc, char *argv[])
   6.243  {
   6.244  	struct test_context ctx;
   6.245  	struct test_set *set;
   6.246  
   6.247 -	if (argc != 3) {
   6.248 -		fprintf(stderr, "usage: %s SETS-FILE TESTS-FILE\n", argv[0]);
   6.249 +	if (argc != 2) {
   6.250 +		fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
   6.251  		exit(-1);			
   6.252  	}
   6.253  
   6.254  	memset(&ctx, 0, sizeof ctx);
   6.255 -	parse_xml_file(argv[1],
   6.256 -		       start_test_sets_element,
   6.257 -		       end_test_sets_element,
   6.258 -		       &ctx);
   6.259 -
   6.260 -	for (set = ctx.sets; set != NULL; set = set->next)
   6.261 -		printf("set %s\n", set->name);
   6.262 +	parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);
   6.263  
   6.264  	return 0;
   6.265  }