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