| 441 | } |
| 442 | |
| 443 | struct htable *htable_check(const struct htable *ht, const char *abortstr) |
| 444 | { |
| 445 | void *p; |
| 446 | struct htable_iter i; |
| 447 | size_t n = 0; |
| 448 | |
| 449 | /* Use non-DEBUG versions here, to avoid infinite recursion with |
| 450 | * CCAN_HTABLE_DEBUG! */ |
| 451 | for (p = htable_first_(ht, &i); p; p = htable_next_(ht, &i)) { |
| 452 | struct htable_iter i2; |
| 453 | void *c; |
| 454 | size_t h = ht->rehash(p, ht->priv); |
| 455 | bool found = false; |
| 456 | |
| 457 | n++; |
| 458 | |
| 459 | /* Open-code htable_get to avoid CCAN_HTABLE_DEBUG */ |
| 460 | for (c = htable_firstval_(ht, &i2, h); |
| 461 | c; |
| 462 | c = htable_nextval_(ht, &i2, h)) { |
| 463 | if (c == p) { |
| 464 | found = true; |
| 465 | break; |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | if (!found) { |
| 470 | if (abortstr) { |
| 471 | fprintf(stderr, |
| 472 | "%s: element %p in position %zu" |
| 473 | " cannot find itself\n", |
| 474 | abortstr, p, i.off); |
| 475 | abort(); |
| 476 | } |
| 477 | return NULL; |
| 478 | } |
| 479 | } |
| 480 | if (n != ht->elems) { |
| 481 | if (abortstr) { |
| 482 | fprintf(stderr, |
| 483 | "%s: found %zu elems, expected %zu\n", |
| 484 | abortstr, n, ht->elems); |
| 485 | abort(); |
| 486 | } |
| 487 | return NULL; |
| 488 | } |
| 489 | |
| 490 | return (struct htable *)ht; |
| 491 | } |