11 #define XML_BUFFER_SIZE 4096
14 parse_xml_file(const char *filename,
15 XML_StartElementHandler start,
16 XML_EndElementHandler end,
23 parser = XML_ParserCreate(NULL);
24 XML_SetElementHandler(parser, start, end);
25 XML_SetUserData(parser, data);
27 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
29 fd = open(filename, O_RDONLY);
31 fprintf(stderr, "failed to open %s: %m\n", filename);
35 while (len = read(fd, buffer, XML_BUFFER_SIZE), len > 0) {
36 err = XML_ParseBuffer(parser, len, len == 0);
37 if (err == XML_STATUS_ERROR) {
38 fprintf(stderr, "parse error at line %lu:\n%s\n",
39 XML_GetCurrentLineNumber(parser),
40 XML_ErrorString(XML_GetErrorCode(parser)));
46 fprintf(stderr, "read: %m\n");
55 struct razor_set *set;
56 struct test_set *next;
60 struct razor_importer *importer;
61 struct test_set *sets;
62 struct razor_package_iterator *package_iterator;
63 struct razor_property_iterator *property_iterator;
67 get_atts(const char **atts, ...)
70 const char *name, **ptr;
74 while (name = va_arg(ap, const char *), name != NULL) {
75 ptr = va_arg(ap, const char **);
77 for (i = 0; atts[i]; i += 2) {
78 if (strcmp(atts[i], name) == 0)
86 parse_property(struct test_context *ctx, const char **atts,
87 enum razor_property_type type)
89 const char *name = NULL, *version = NULL;
91 get_atts(atts, "name", &name, "eq", &version, NULL);
94 fprintf(stderr, "no name specified for property\n");
98 razor_importer_add_property(ctx->importer, name, version, type);
102 start_set_element(void *data, const char *element, const char **atts)
104 struct test_context *ctx = data;
105 struct test_set *set;
106 const char *name, *version;
108 if (strcmp(element, "set") == 0) {
109 get_atts(atts, "name", &name, NULL);
110 ctx->importer = razor_importer_new();
111 set = malloc(sizeof *set);
112 set->name = strdup(name);
113 set->next = ctx->sets;
115 } else if (strcmp(element, "package") == 0) {
116 get_atts(atts, "name", &name, "version", &version, NULL);
117 razor_importer_begin_package(ctx->importer, name, version);
118 } else if (strcmp(element, "requires") == 0) {
119 parse_property(ctx, atts, RAZOR_PROPERTY_REQUIRES);
120 } else if (strcmp(element, "provides") == 0) {
121 parse_property(ctx, atts, RAZOR_PROPERTY_PROVIDES);
122 } else if (strcmp(element, "obsoletes") == 0) {
123 parse_property(ctx, atts, RAZOR_PROPERTY_OBSOLETES);
124 } else if (strcmp(element, "conflicts") == 0) {
125 parse_property(ctx, atts, RAZOR_PROPERTY_CONFLICTS);
126 } else if (strcmp(element, "file") == 0) {
127 get_atts(atts, "name", &name, NULL);
128 razor_importer_add_file(ctx->importer, name);
129 } else if (strcmp(element, "dir") == 0) {
130 get_atts(atts, "name", &name, NULL);
131 razor_importer_add_file(ctx->importer, name);
136 end_set_element (void *data, const char *name)
138 struct test_context *ctx = data;
140 if (strcmp(name, "set") == 0) {
141 ctx->sets->set = razor_importer_finish(ctx->importer);
142 } else if (strcmp(name, "package") == 0) {
143 razor_importer_finish_package(ctx->importer);
147 static struct razor_set *
148 lookup_set(struct test_context *ctx, const char *name)
150 struct test_set *set;
152 for (set = ctx->sets; set != NULL; set = set->next) {
153 if (strcmp(set->name, name) == 0)
161 verify_begin(struct test_context *ctx, const char **atts)
163 struct razor_set *set;
164 const char *type, *name;
166 get_atts(atts, "type", &type, "set", &name, NULL);
167 set = lookup_set(ctx, name);
169 fprintf(stderr, "set %s not found\n", name);
173 if (strcmp(type, "packages") == 0) {
174 ctx->package_iterator =
175 razor_package_iterator_create(set);
176 } else if (strcmp(type, "properties") == 0) {
177 ctx->property_iterator =
178 razor_property_iterator_create(set, NULL);
181 "unknown compare type \"%s\"\n", type);
187 verify_end(struct test_context *ctx)
189 struct razor_package *package;
190 struct razor_property *property;
191 const char *name, *version;
192 enum razor_property_type type;
194 if (ctx->package_iterator != NULL) {
195 if (razor_package_iterator_next(ctx->package_iterator,
198 fprintf(stderr, "too few packages in set\n");
202 razor_package_iterator_destroy(ctx->package_iterator);
203 ctx->package_iterator = NULL;
206 if (ctx->property_iterator != NULL) {
207 if (razor_property_iterator_next(ctx->property_iterator,
209 &name, &version, &type)) {
210 fprintf(stderr, "too few properties in set\n");
214 razor_property_iterator_destroy(ctx->property_iterator);
215 ctx->property_iterator = NULL;
220 verify_package(struct test_context *ctx, const char **atts)
222 struct razor_package *package;
223 const char *name, *version, *ref_name, *ref_version;
225 if (ctx->package_iterator == NULL) {
227 "\"package\" element seen, "
228 "but not in package verify mode\n");
232 get_atts(atts, "name", &ref_name, "version", &ref_version, NULL);
233 if (!razor_package_iterator_next(ctx->package_iterator,
234 &package, &name, &version)) {
235 fprintf(stderr, "too many packages in set\n");
239 if (strcmp(name, ref_name) != 0 || strcmp(version, ref_version) != 0) {
241 "package mismatch; expected %s-%s, got %s-%s\n",
242 ref_name, ref_version, name, version);
248 verify_property(struct test_context *ctx,
249 enum razor_property_type ref_type, const char **atts)
251 struct razor_property *property;
252 const char *name, *version, *ref_name, *ref_version;
253 enum razor_property_type type;
256 if (ctx->property_iterator == NULL) {
258 "\"requires/provides\" element seen, "
259 "but not in property verify mode\n");
263 get_atts(atts, "name", &ref_name, "eq", &ref_version, NULL);
264 if (!razor_property_iterator_next(ctx->property_iterator, &property,
265 &name, &version, &type)) {
266 fprintf(stderr, "too many properties in set\n");
270 if (version != NULL && ref_version != NULL)
271 same_version = strcmp(version, ref_version) == 0;
272 else if (version == NULL && ref_version == NULL)
277 if (strcmp(name, ref_name) != 0 || !same_version || type != ref_type) {
279 "property mismatch; expected %s-%s/%d, got %s-%s/%d\n",
280 ref_name, ref_version, ref_type,
281 name, version, type);
287 start_test_element(void *data, const char *element, const char **atts)
289 struct test_context *ctx = data;
292 if (strcmp(element, "import") == 0) {
293 get_atts(atts, "file", &name, NULL);
294 parse_xml_file(name, start_set_element, end_set_element, ctx);
295 } else if (strcmp(element, "update") == 0) {
296 /* run update to create new set */
297 } else if (strcmp(element, "verify") == 0) {
298 verify_begin(ctx, atts);
299 } else if (strcmp(element, "package") == 0) {
300 verify_package(ctx, atts);
301 } else if (strcmp(element, "requires") == 0) {
302 verify_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
303 } else if (strcmp(element, "provides") == 0) {
304 verify_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
305 } else if (strcmp(element, "conflicts") == 0) {
306 verify_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
307 } else if (strcmp(element, "obsoletes") == 0) {
308 verify_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
313 end_test_element (void *data, const char *element)
315 struct test_context *ctx = data;
317 if (strcmp(element, "verify") == 0)
321 int main(int argc, char *argv[])
323 struct test_context ctx;
326 fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
330 memset(&ctx, 0, sizeof ctx);
331 parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);