| 671 | before the transition from LOT's settings. */ |
| 672 | |
| 673 | static time_t |
| 674 | hunt(timezone_t tz, time_t lot, time_t hit, bool only_ok) |
| 675 | { |
| 676 | static char * loab; |
| 677 | static ptrdiff_t loabsize; |
| 678 | struct tm lotm; |
| 679 | struct tm tm; |
| 680 | |
| 681 | /* Convert LOT into a broken-down time here, even though our |
| 682 | caller already did that. On platforms without TM_ZONE, |
| 683 | tzname may have been altered since our caller broke down |
| 684 | LOT, and tzname needs to be changed back. */ |
| 685 | bool lotm_ok = localtime_rz(tz, &lot, &lotm) != NULL; |
| 686 | bool tm_ok; |
| 687 | char const *ab = lotm_ok ? saveabbr(&loab, &loabsize, &lotm) : NULL; |
| 688 | |
| 689 | for ( ; ; ) { |
| 690 | /* T = average of LOT and HIT, rounding down. |
| 691 | Avoid overflow. */ |
| 692 | int rem_sum = lot % 2 + hit % 2; |
| 693 | time_t t = (rem_sum == 2) - (rem_sum < 0) + lot / 2 + hit / 2; |
| 694 | if (t == lot) |
| 695 | break; |
| 696 | tm_ok = localtime_rz(tz, &t, &tm) != NULL; |
| 697 | if (lotm_ok == tm_ok |
| 698 | && (only_ok |
| 699 | || (ab && tm.tm_isdst == lotm.tm_isdst |
| 700 | && delta(&tm, &lotm) == t - lot |
| 701 | && strcmp(abbr(&tm), ab) == 0))) { |
| 702 | lot = t; |
| 703 | if (tm_ok) |
| 704 | lotm = tm; |
| 705 | } else hit = t; |
| 706 | } |
| 707 | return hit; |
| 708 | } |
| 709 | |
| 710 | /* |
| 711 | ** Thanks to Paul Eggert for logic used in delta_nonneg. |
no test coverage detected