| 4117 | if (t2 < 0 |
| 4118 | ? ZIC_MAX / t2 <= t1 && (t2 == -1 || t1 <= ZIC_MIN / t2) |
| 4119 | : t2 == 0 || (ZIC_MIN / t2 <= t1 && t1 <= ZIC_MAX / t2)) |
| 4120 | return t1 * t2; |
| 4121 | #endif |
| 4122 | time_overflow(); |
| 4123 | } |
| 4124 | |
| 4125 | /* |
| 4126 | ** Given a rule, and a year, compute the date (in seconds since January 1, |
| 4127 | ** 1970, 00:00 LOCAL time) in that year that the rule refers to. |
| 4128 | ** Do not count leap seconds. On error, diagnose and exit. |
| 4129 | */ |
| 4130 | |
| 4131 | static zic_t |
| 4132 | rpytime(const struct rule *rp, zic_t wantedy) |
| 4133 | { |
| 4134 | register int m, i; |
| 4135 | register zic_t dayoff; /* with a nod to Margaret O. */ |
| 4136 | register zic_t t, y; |
| 4137 | int yrem; |
| 4138 | |
| 4139 | m = TM_JANUARY; |
| 4140 | y = EPOCH_YEAR; |
| 4141 | |
| 4142 | /* dayoff = floor((wantedy - y) / YEARSPERREPEAT) * DAYSPERREPEAT, |
| 4143 | checking for overflow. */ |
| 4144 | yrem = wantedy % YEARSPERREPEAT - y % YEARSPERREPEAT; |
| 4145 | dayoff = omul ((wantedy / YEARSPERREPEAT - y / YEARSPERREPEAT |
| 4146 | + yrem / YEARSPERREPEAT - (yrem % YEARSPERREPEAT < 0)), |
| 4147 | DAYSPERREPEAT); |
| 4148 | /* wantedy = y + ((wantedy - y) mod YEARSPERREPEAT), sans overflow. */ |
| 4149 | wantedy = y + (yrem + 2 * YEARSPERREPEAT) % YEARSPERREPEAT; |
| 4150 | |
| 4151 | while (wantedy != y) { |
| 4152 | i = len_years[isleap(y)]; |
| 4153 | dayoff = oadd(dayoff, i); |
| 4154 | y++; |
| 4155 | } |
| 4156 | while (m != rp->r_month) { |
| 4157 | i = len_months[isleap(y)][m]; |
| 4158 | dayoff = oadd(dayoff, i); |
| 4159 | ++m; |
| 4160 | } |
| 4161 | i = rp->r_dayofmonth; |
| 4162 | if (m == TM_FEBRUARY && i == 29 && !isleap(y)) { |
| 4163 | if (rp->r_dycode == DC_DOWLEQ) |
| 4164 | --i; |
| 4165 | else { |
| 4166 | error(N_("use of 2/29 in non leap-year")); |
| 4167 | exit(EXIT_FAILURE); |
| 4168 | } |
| 4169 | } |
| 4170 | --i; |
| 4171 | dayoff = oadd(dayoff, i); |
| 4172 | if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { |
| 4173 | /* |
| 4174 | ** Don't trust mod of negative numbers. |
| 4175 | */ |
| 4176 | zic_t wday = ((EPOCH_WDAY + dayoff % DAYSPERWEEK + DAYSPERWEEK) |