another checkpoint...
there are a bunch of problems with doing things this way, and file
provide removals are currently unhandled
1.1 --- a/razor.c Fri Mar 07 08:24:09 2008 -0500
1.2 +++ b/razor.c Fri Mar 07 08:52:09 2008 -0500
1.3 @@ -1965,24 +1965,53 @@
1.4 return pkg;
1.5 }
1.6
1.7 +static struct razor_property *
1.8 +skip_to_matching_property(struct razor_transaction_resolver *trans,
1.9 + struct razor_property *match,
1.10 + struct razor_property *prop)
1.11 +{
1.12 + struct razor_set *mset, *pset;
1.13 + const char *ppool, *mpool;
1.14 + struct razor_property *prop_end;
1.15 +
1.16 + if (property_in_set(match, trans->system))
1.17 + mset = trans->system;
1.18 + else
1.19 + mset = trans->upstream;
1.20 +
1.21 + if (property_in_set(prop, trans->system))
1.22 + pset = trans->system;
1.23 + else if (property_in_set(prop, trans->upstream))
1.24 + pset = trans->upstream;
1.25 + else
1.26 + return prop;
1.27 +
1.28 + prop_end = pset->properties.data + pset->properties.size;
1.29 + ppool = pset->string_pool.data;
1.30 + mpool = mset->string_pool.data;
1.31 +
1.32 + while (prop < prop_end &&
1.33 + strcmp(&ppool[prop->name], &mpool[match->name]) < 0)
1.34 + prop++;
1.35 + return prop;
1.36 +}
1.37 +
1.38 static struct razor_package *
1.39 find_package_matching(struct razor_transaction_resolver *trans, int installed,
1.40 - struct razor_property **start_prop,
1.41 + struct razor_property *prop,
1.42 struct razor_property *req,
1.43 struct razor_set *req_set)
1.44 {
1.45 struct razor_set *set;
1.46 struct bitarray *pkgbits;
1.47 struct razor_package *pkgs;
1.48 - struct razor_property *prop, *props, *prop_end;
1.49 + struct razor_property *props, *prop_end;
1.50 enum razor_property_type match_type;
1.51 const char *pool;
1.52 - const char *rpool = req_set->string_pool.data;
1.53 - int match_name = (req->type == RAZOR_PROPERTY_OBSOLETES ||
1.54 - req->type == RAZOR_PROPERTY_CONFLICTS);
1.55 + const char *rpool;
1.56 + int match_name = (req->type == RAZOR_PROPERTY_OBSOLETES);
1.57 int match;
1.58
1.59 - prop = *start_prop;
1.60 if (property_in_set(prop, trans->system)) {
1.61 set = trans->system;
1.62 pkgbits = &trans->syspkgs;
1.63 @@ -1992,6 +2021,14 @@
1.64 } else
1.65 return NULL;
1.66
1.67 + if (!req_set) {
1.68 + if (property_in_set(req, trans->system))
1.69 + req_set = trans->system;
1.70 + else
1.71 + req_set = trans->upstream;
1.72 + }
1.73 + rpool = req_set->string_pool.data;
1.74 +
1.75 if (req->type == RAZOR_PROPERTY_PROVIDES)
1.76 match_type = RAZOR_PROPERTY_CONFLICTS;
1.77 else
1.78 @@ -2006,7 +2043,6 @@
1.79 while (prop < prop_end &&
1.80 strcmp(&pool[prop->name], &rpool[req->name]) < 0)
1.81 prop++;
1.82 - *start_prop = prop;
1.83 if (prop == prop_end ||
1.84 strcmp(&pool[prop->name], &rpool[req->name]) > 0)
1.85 return NULL;
1.86 @@ -2048,27 +2084,29 @@
1.87
1.88 static struct razor_package *
1.89 find_installed_package_for_property(struct razor_transaction_resolver *trans,
1.90 - struct razor_property **sys_sp,
1.91 + struct razor_property *sys_start,
1.92 + struct razor_property *up_start,
1.93 struct razor_property *req)
1.94 {
1.95 struct razor_package *pkg;
1.96
1.97 - pkg = find_package_matching(trans, 1, sys_sp, req, trans->upstream);
1.98 + pkg = find_package_matching(trans, 1, sys_start, req, NULL);
1.99 if (!pkg)
1.100 - pkg = find_package_matching(trans, 1, &req, req, trans->upstream);
1.101 + pkg = find_package_matching(trans, 1, up_start, req, NULL);
1.102 return pkg;
1.103 }
1.104
1.105 static struct razor_package *
1.106 find_uninstalled_package_for_property(struct razor_transaction_resolver *trans,
1.107 - struct razor_property **sys_sp,
1.108 + struct razor_property *sys_start,
1.109 + struct razor_property *up_start,
1.110 struct razor_property *req)
1.111 {
1.112 struct razor_package *pkg;
1.113
1.114 - pkg = find_package_matching(trans, 0, sys_sp, req, trans->upstream);
1.115 + pkg = find_package_matching(trans, 0, up_start, req, NULL);
1.116 if (!pkg)
1.117 - pkg = find_package_matching(trans, 0, &req, req, trans->upstream);
1.118 + pkg = find_package_matching(trans, 0, sys_start, req, NULL);
1.119 return pkg;
1.120 }
1.121
1.122 @@ -2100,7 +2138,7 @@
1.123 else
1.124 req.relation = RAZOR_VERSION_GREATER;
1.125
1.126 - return find_package_matching(trans, 0, &up, &req, set);
1.127 + return find_package_matching(trans, 0, up, &req, set);
1.128 }
1.129
1.130 /* FIXME */
1.131 @@ -2256,7 +2294,9 @@
1.132
1.133 tp->state = state;
1.134 if (state != RAZOR_PACKAGE_INSTALL &&
1.135 - state != RAZOR_PACKAGE_REMOVE)
1.136 + state != RAZOR_PACKAGE_FORCED_UPDATE &&
1.137 + state != RAZOR_PACKAGE_REMOVE &&
1.138 + state != RAZOR_PACKAGE_OBSOLETED)
1.139 trans->errors++;
1.140
1.141 if (contradiction) {
1.142 @@ -2291,26 +2331,6 @@
1.143 }
1.144
1.145 /* FIXME: make this more efficient */
1.146 -static void
1.147 -maybe_mark_upgraded(struct razor_transaction_resolver *trans,
1.148 - struct razor_package *pkg)
1.149 -{
1.150 - struct razor_package *spkgs, *sp, *send;
1.151 - const char *spool, *upool;
1.152 -
1.153 - sp = spkgs = trans->system->packages.data;
1.154 - send = trans->system->packages.data + trans->system->packages.size;
1.155 - spool = trans->system->string_pool.data;
1.156 - upool = trans->upstream->string_pool.data;
1.157 -
1.158 - while (sp < send &&
1.159 - strcmp(&spool[sp->name], &upool[pkg->name]) < 0)
1.160 - sp++;
1.161 - if (sp < send && strcmp(&spool[sp->name], &upool[pkg->name]) == 0)
1.162 - bitarray_set(&trans->syspkgs, sp - spkgs, 0);
1.163 -}
1.164 -
1.165 -/* FIXME: this too */
1.166 static struct razor_package *
1.167 find_old_version(struct razor_transaction_resolver *trans,
1.168 struct razor_package *pkg)
1.169 @@ -2362,13 +2382,14 @@
1.170 up++;
1.171 if (up == uprop_end)
1.172 break;
1.173 + sp = skip_to_matching_property(trans, up, sp);
1.174
1.175 switch (up->type) {
1.176 case RAZOR_PROPERTY_REQUIRES:
1.177 if (!strncmp(&upool[up->name], "rpmlib(", 7))
1.178 break;
1.179
1.180 - if (find_installed_package_for_property(trans, &sp, up) ||
1.181 + if (find_installed_package_for_property(trans, sp, up, up) ||
1.182 find_installed_package_for_file(trans, &upool[up->name])) {
1.183 /* Requires something that is either installed
1.184 * or to-be-installed.
1.185 @@ -2377,14 +2398,9 @@
1.186 }
1.187
1.188 /* See if we can install a new upstream provider */
1.189 - pkg = find_uninstalled_package_for_property(trans, &sp, up);
1.190 - if (!pkg) {
1.191 + pkg = find_uninstalled_package_for_property(trans, sp, up, up);
1.192 + if (!pkg)
1.193 pkg = find_uninstalled_package_for_file(trans, &upool[up->name]);
1.194 - if (pkg) {
1.195 - /* FIXME: find a way to do this more efficiently */
1.196 - maybe_mark_upgraded(trans, pkg);
1.197 - }
1.198 - }
1.199 add_transaction_package(trans, pkg, find_old_version(trans, pkg),
1.200 RAZOR_PACKAGE_INSTALL,
1.201 NULL, up);
1.202 @@ -2394,7 +2410,7 @@
1.203 /* find_installed_package_for_property works backwards
1.204 * here, finding a *conflicting* installed package.
1.205 */
1.206 - pkg = find_installed_package_for_property(trans, &sp, up);
1.207 + pkg = find_installed_package_for_property(trans, sp, up, up);
1.208 if (!pkg)
1.209 break;
1.210
1.211 @@ -2404,7 +2420,6 @@
1.212 */
1.213 upgrade = find_upgrade_for_installed_conflict(trans, pkg, up);
1.214 if (upgrade) {
1.215 - bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.216 add_transaction_package(trans, upgrade, pkg,
1.217 RAZOR_PACKAGE_INSTALL,
1.218 &spool[pkg->name], sp);
1.219 @@ -2418,7 +2433,7 @@
1.220 break;
1.221
1.222 case RAZOR_PROPERTY_CONFLICTS:
1.223 - pkg = find_installed_package_for_property(trans, &sp, up);
1.224 + pkg = find_installed_package_for_property(trans, sp, up, up);
1.225 if (!pkg)
1.226 break;
1.227
1.228 @@ -2428,7 +2443,6 @@
1.229 */
1.230 upgrade = find_upgrade(trans, sp, up);
1.231 if (upgrade) {
1.232 - bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
1.233 add_transaction_package(trans, upgrade, pkg,
1.234 RAZOR_PACKAGE_INSTALL,
1.235 NULL, up);
1.236 @@ -2442,13 +2456,13 @@
1.237 break;
1.238
1.239 case RAZOR_PROPERTY_OBSOLETES:
1.240 - pkg = find_installed_package_for_property(trans, &sp, up);
1.241 + pkg = find_installed_package_for_property(trans, sp, up, up);
1.242 if (pkg) {
1.243 /* If pkg is to-be-installed, this
1.244 * will add a CONTRADICTION error as well.
1.245 */
1.246 add_transaction_package(trans, NULL, pkg,
1.247 - RAZOR_PACKAGE_REMOVE,
1.248 + RAZOR_PACKAGE_OBSOLETED,
1.249 NULL, up);
1.250 }
1.251 break;
1.252 @@ -2461,6 +2475,7 @@
1.253 }
1.254 }
1.255
1.256 +#if 0
1.257 /* Look through pkg's PROVIDES, and for each one that no other package
1.258 * provides, add its property index to lost_provides.
1.259 */
1.260 @@ -2571,7 +2586,9 @@
1.261 for (r = start; r < end; r++) {
1.262 if (!packages[r].old_package ||
1.263 (packages[r].state != RAZOR_PACKAGE_REMOVE &&
1.264 - packages[r].state != RAZOR_PACKAGE_INSTALL))
1.265 + packages[r].state != RAZOR_PACKAGE_INSTALL &&
1.266 + packages[r].state != RAZOR_PACKAGE_FORCED_UPDATE &&
1.267 + packages[r].state != RAZOR_PACKAGE_OBSOLETED)
1.268 continue;
1.269
1.270 gather_lost_provides(trans->system, packages[r].old_package,
1.271 @@ -2624,6 +2641,196 @@
1.272 }
1.273 array_release(&lost_files);
1.274 }
1.275 +#endif
1.276 +
1.277 +static struct razor_package *
1.278 +find_upgrade_for_lost_requirement(struct razor_transaction_resolver *trans,
1.279 + struct razor_package *pkg,
1.280 + struct razor_property *req)
1.281 +{
1.282 + struct razor_package *upkgs, *up, *uend;
1.283 + struct razor_property *uprops;
1.284 + const char *spool, *upool;
1.285 + struct list *prop;
1.286 +
1.287 + up = upkgs = trans->upstream->packages.data;
1.288 + uend = trans->upstream->packages.data + trans->upstream->packages.size;
1.289 + upool = trans->upstream->string_pool.data;
1.290 + uprops = trans->upstream->properties.data;
1.291 + spool = trans->system->string_pool.data;
1.292 +
1.293 + while (up < uend &&
1.294 + strcmp(&upool[up->name], &spool[pkg->name]) < 0)
1.295 + up++;
1.296 + if (up == uend || strcmp(&upool[up->name], &spool[pkg->name]) != 0)
1.297 + return NULL;
1.298 +
1.299 + for (prop = list_first(&up->properties, &trans->system->property_pool); prop; prop = list_next(prop)) {
1.300 + if (uprops[prop->data].type == RAZOR_PROPERTY_REQUIRES &&
1.301 + strcmp(&upool[uprops[prop->data].name], &spool[req->name]) == 0 &&
1.302 + uprops[prop->data].relation == req->relation &&
1.303 + strcmp(&upool[uprops[prop->data].version], &spool[req->version]) == 0)
1.304 + return NULL;
1.305 + }
1.306 + return up;
1.307 +}
1.308 +
1.309 +static int
1.310 +prop_is_being_removed(struct razor_transaction_resolver *trans,
1.311 + struct razor_property *prop)
1.312 +{
1.313 + struct list *pkg;
1.314 +
1.315 + for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
1.316 + if (bitarray_get(&trans->syspkgs, pkg->data))
1.317 + return 0;
1.318 + }
1.319 + return 1;
1.320 +}
1.321 +
1.322 +static int
1.323 +prop_is_being_updated(struct razor_transaction_resolver *trans,
1.324 + struct razor_property *prop)
1.325 +{
1.326 + struct razor_package *packages = trans->system->packages.data;
1.327 + const char *pool = trans->system->string_pool.data;
1.328 + struct razor_transaction_package *tp;
1.329 + struct list *pkg;
1.330 +
1.331 + /* Assumes prop_is_being_removed returns true */
1.332 +
1.333 + for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
1.334 + tp = find_transaction_package(trans, &pool[packages[pkg->data].name]);
1.335 + if (tp && tp->state == RAZOR_PACKAGE_REMOVE)
1.336 + return 0;
1.337 + }
1.338 + return 1;
1.339 +}
1.340 +
1.341 +static void
1.342 +razor_transaction_satisfy_removes(struct razor_transaction_resolver *trans)
1.343 +{
1.344 + struct razor_package *spkgs, *upkgs, *pkg, *upgrade;
1.345 + struct razor_property *sp, *sprops, *sprop_end, *sr;
1.346 + struct razor_property *up, *uprops, *uprop_end, *ur, *first_up;
1.347 + const char *spool, *upool, *removed_package;
1.348 + struct list *reqpkg;
1.349 +
1.350 + spkgs = trans->system->packages.data;
1.351 + sprops = trans->system->properties.data;
1.352 + sprop_end = trans->system->properties.data + trans->system->properties.size;
1.353 + spool = trans->system->string_pool.data;
1.354 + upkgs = trans->upstream->packages.data;
1.355 + uprops = trans->upstream->properties.data;
1.356 + uprop_end = trans->upstream->properties.data + trans->upstream->properties.size;
1.357 + upool = trans->upstream->string_pool.data;
1.358 +
1.359 + up = uprops;
1.360 + for (sp = sprops; sp < sprop_end; sp++) {
1.361 + /* Skip 'sp' ahead to a PROVIDES of a package which is
1.362 + * to-be-removed.
1.363 + */
1.364 + while (sp < sprop_end &&
1.365 + (sp->type != RAZOR_PROPERTY_PROVIDES ||
1.366 + !prop_is_being_removed(trans, sp)))
1.367 + sp++;
1.368 + if (sp == sprop_end)
1.369 + break;
1.370 +
1.371 + removed_package = &spool[spkgs[list_first(&sp->packages, &trans->system->package_pool)->data].name];
1.372 +
1.373 + /* Skip 'up' to match */
1.374 + up = skip_to_matching_property(trans, sp, up);
1.375 + ur = first_up = up;
1.376 +
1.377 + /* If the package is just being upgraded, we may
1.378 + * already be installing an identical PROVIDES, so
1.379 + * check for that.
1.380 + */
1.381 + while (up < uprop_end &&
1.382 + strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
1.383 + (up->type != RAZOR_PROPERTY_PROVIDES ||
1.384 + sp->relation != up->relation ||
1.385 + strcmp(&spool[sp->name], &upool[up->name]) != 0))
1.386 + up++;
1.387 + if (up < uprop_end &&
1.388 + up->type == RAZOR_PROPERTY_PROVIDES &&
1.389 + strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
1.390 + sp->relation == up->relation &&
1.391 + strcmp(&spool[sp->version], &upool[up->version]) == 0 &&
1.392 + prop_is_being_installed(trans, up)) {
1.393 + up = first_up;
1.394 + continue;
1.395 + }
1.396 + up = first_up;
1.397 +
1.398 + /* For all still-installed packages that require
1.399 + * sp->name, see if they are satisfied by any other
1.400 + * still-installed or to-be-installed property. If
1.401 + * not, either remove or attempt to update the
1.402 + * package, depending on why the required property has
1.403 + * disappeared
1.404 + */
1.405 + sr = sp;
1.406 + while (sr > sprops + 1 && (sr - 1)->name == sr->name)
1.407 + sr--;
1.408 + for (; sr->type == RAZOR_PROPERTY_REQUIRES; sr++) {
1.409 + if (prop_is_being_removed(trans, sr))
1.410 + continue;
1.411 + if (find_installed_package_for_property(trans, sp, up, sr))
1.412 + continue;
1.413 +
1.414 + for (reqpkg = list_first(&sr->packages, &trans->system->package_pool); reqpkg; reqpkg = list_next(reqpkg)) {
1.415 + if (!bitarray_get(&trans->syspkgs, reqpkg->data))
1.416 + continue;
1.417 + pkg = &spkgs[reqpkg->data];
1.418 + if (prop_is_being_updated(trans, sp)) {
1.419 + upgrade = find_upgrade_for_lost_requirement(trans, pkg, sr);
1.420 + if (upgrade) {
1.421 + add_transaction_package(trans, upgrade, pkg,
1.422 + RAZOR_PACKAGE_FORCED_UPDATE,
1.423 + removed_package, NULL);
1.424 + } else {
1.425 + /* This will cause a CONTRADICTION */
1.426 + add_transaction_package(trans, pkg, NULL,
1.427 + RAZOR_PACKAGE_INSTALL,
1.428 + removed_package, sr);
1.429 + }
1.430 + } else {
1.431 + add_transaction_package(trans, NULL, pkg,
1.432 + RAZOR_PACKAGE_REMOVE,
1.433 + removed_package, sr);
1.434 + }
1.435 + }
1.436 + }
1.437 +
1.438 +#if 0
1.439 + /* Likewise with to-be-installed packages (in this
1.440 + * case we can't actually remove them, but
1.441 + * add_transaction_package will handle creating the
1.442 + * error entry).
1.443 + */
1.444 + ur = first_up;
1.445 + while (ur > uprops + 1 && (ur - 1)->name == ur->name)
1.446 + ur--;
1.447 + for (; ur->type == RAZOR_PROPERTY_REQUIRES; ur++) {
1.448 + if (!prop_is_being_installed(trans, ur))
1.449 + continue;
1.450 + if (find_installed_package_for_property(trans, sp, up, ur))
1.451 + continue;
1.452 +
1.453 + for (reqpkg = list_first(&ur->packages, &trans->upstream->package_pool); reqpkg; reqpkg = list_next(reqpkg)) {
1.454 + if (!bitarray_get(&trans->uppkgs, reqpkg->data))
1.455 + continue;
1.456 + pkg = &upkgs[reqpkg->data];
1.457 + add_transaction_package(trans, NULL, pkg,
1.458 + RAZOR_PACKAGE_REMOVE,
1.459 + NULL, sr);
1.460 + }
1.461 + }
1.462 +#endif
1.463 + }
1.464 +}
1.465
1.466 struct razor_transaction *
1.467 razor_transaction_create(struct razor_set *system, struct razor_set *upstream,
1.468 @@ -2653,7 +2860,7 @@
1.469
1.470 while (!trans.errors && start != end) {
1.471 razor_transaction_satisfy_installs(&trans);
1.472 - razor_transaction_satisfy_removes(&trans, start, end);
1.473 + razor_transaction_satisfy_removes(&trans);
1.474
1.475 start = end;
1.476 end = trans.packages.size / sizeof (struct razor_transaction_package);
1.477 @@ -2721,20 +2928,34 @@
1.478 printf("\n");
1.479 break;
1.480
1.481 + case RAZOR_PACKAGE_FORCED_UPDATE:
1.482 + if (errors_only)
1.483 + break;
1.484 +
1.485 + printf("Updating %s to %s due to update of %s\n",
1.486 + p->name, p->new_version, p->dep_package);
1.487 + break;
1.488 +
1.489 case RAZOR_PACKAGE_REMOVE:
1.490 if (errors_only)
1.491 break;
1.492 printf("Removing %s %s", p->name, p->old_version);
1.493 if (p->dep_package) {
1.494 - if (p->dep_type == RAZOR_PROPERTY_OBSOLETES) {
1.495 - printf(" which is obsoleted by %s",
1.496 - p->dep_package);
1.497 - } else {
1.498 - printf(" which required %s",
1.499 - p->dep_package);
1.500 - if (strcmp(p->dep_property, p->name) != 0)
1.501 - printf(" for %s", p->dep_property);
1.502 - }
1.503 + printf(" which required %s",
1.504 + p->dep_package);
1.505 + if (strcmp(p->dep_property, p->name) != 0)
1.506 + printf(" for %s", p->dep_property);
1.507 + }
1.508 + printf("\n");
1.509 + break;
1.510 +
1.511 + case RAZOR_PACKAGE_OBSOLETED:
1.512 + if (errors_only)
1.513 + break;
1.514 + printf("Removing %s %s", p->name, p->old_version);
1.515 + if (p->dep_package) {
1.516 + printf(" which is obsoleted by %s",
1.517 + p->dep_package);
1.518 }
1.519 printf("\n");
1.520 break;
2.1 --- a/razor.h Fri Mar 07 08:24:09 2008 -0500
2.2 +++ b/razor.h Fri Mar 07 08:52:09 2008 -0500
2.3 @@ -77,7 +77,9 @@
2.4 enum razor_transaction_package_state {
2.5 /* Basic states */
2.6 RAZOR_PACKAGE_INSTALL,
2.7 + RAZOR_PACKAGE_FORCED_UPDATE,
2.8 RAZOR_PACKAGE_REMOVE,
2.9 + RAZOR_PACKAGE_OBSOLETED,
2.10
2.11 /* Error states */
2.12
2.13 @@ -94,7 +96,7 @@
2.14 /* Already-installed package has a conflict against this package */
2.15 RAZOR_PACKAGE_OLD_CONFLICT,
2.16 /* Requirement of to-be-installed package can't be satisfied */
2.17 - RAZOR_PACKAGE_UNSATISFIABLE
2.18 + RAZOR_PACKAGE_UNSATISFIABLE,
2.19 };
2.20
2.21 struct razor_transaction_package {
3.1 --- a/test-driver.c Fri Mar 07 08:24:09 2008 -0500
3.2 +++ b/test-driver.c Fri Mar 07 08:52:09 2008 -0500
3.3 @@ -64,9 +64,9 @@
3.4 char *install_pkgs[3], *remove_pkgs[3];
3.5 int n_install_pkgs, n_remove_pkgs;
3.6
3.7 - int in_result, result_errors;
3.8 + int in_result;
3.9
3.10 - int debug;
3.11 + int debug, errors;
3.12 };
3.13
3.14 static void
3.15 @@ -214,7 +214,7 @@
3.16
3.17 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
3.18 name, razor_version_relations[rel], version);
3.19 - exit(1);
3.20 + ctx->errors++;
3.21 }
3.22
3.23 static void
3.24 @@ -317,7 +317,7 @@
3.25 {
3.26 struct test_context *ctx = data;
3.27
3.28 - ctx->result_errors++;
3.29 + ctx->errors++;
3.30 if (old_version) {
3.31 fprintf(stderr, " result set should not contain %s %s\n",
3.32 name, old_version);
3.33 @@ -335,11 +335,8 @@
3.34 if (ctx->result_set) {
3.35 if (!ctx->system_set)
3.36 ctx->system_set = razor_set_create();
3.37 - ctx->result_errors = 0;
3.38 razor_set_diff(ctx->system_set, ctx->result_set,
3.39 diff_callback, ctx);
3.40 - if (ctx->result_errors)
3.41 - exit(1);
3.42 }
3.43 }
3.44
3.45 @@ -443,5 +440,9 @@
3.46
3.47 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
3.48
3.49 - return 0;
3.50 + if (ctx.errors) {
3.51 + fprintf(stderr, "\n%d errors\n", ctx.errors);
3.52 + return 1;
3.53 + } else
3.54 + return 0;
3.55 }