| 3197 | } |
| 3198 | return len; |
| 3199 | } |
| 3200 | |
| 3201 | static int |
| 3202 | stringrule(char *result, struct rule *const rp, zic_t save, zic_t stdoff) |
| 3203 | { |
| 3204 | register zic_t tod = rp->r_tod; |
| 3205 | register int compat = 0; |
| 3206 | |
| 3207 | if (rp->r_dycode == DC_DOM) { |
| 3208 | register int month, total; |
| 3209 | |
| 3210 | if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) |
| 3211 | return -1; |
| 3212 | total = 0; |
| 3213 | for (month = 0; month < rp->r_month; ++month) |
| 3214 | total += len_months[0][month]; |
| 3215 | /* Omit the "J" in Jan and Feb, as that's shorter. */ |
| 3216 | if (rp->r_month <= 1) |
| 3217 | result += sprintf(result, "%d", total + rp->r_dayofmonth - 1); |
| 3218 | else |
| 3219 | result += sprintf(result, "J%d", total + rp->r_dayofmonth); |
| 3220 | } else { |
| 3221 | register int week; |
| 3222 | register int wday = rp->r_wday; |
| 3223 | register int wdayoff; |
| 3224 | |
| 3225 | if (rp->r_dycode == DC_DOWGEQ) { |
| 3226 | wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK; |
| 3227 | if (wdayoff) |
| 3228 | compat = 2013; |
| 3229 | wday -= wdayoff; |
| 3230 | tod += wdayoff * SECSPERDAY; |
| 3231 | week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK; |
| 3232 | } else if (rp->r_dycode == DC_DOWLEQ) { |
| 3233 | if (rp->r_dayofmonth == len_months[1][rp->r_month]) |
| 3234 | week = 5; |
| 3235 | else { |
| 3236 | wdayoff = rp->r_dayofmonth % DAYSPERWEEK; |
| 3237 | if (wdayoff) |
| 3238 | compat = 2013; |
| 3239 | wday -= wdayoff; |
| 3240 | tod += wdayoff * SECSPERDAY; |
| 3241 | week = rp->r_dayofmonth / DAYSPERWEEK; |
| 3242 | } |
| 3243 | } else return -1; /* "cannot happen" */ |
| 3244 | if (wday < 0) |
| 3245 | wday += DAYSPERWEEK; |
| 3246 | result += sprintf(result, "M%d.%d.%d", |
| 3247 | rp->r_month + 1, week, wday); |
| 3248 | } |
| 3249 | if (rp->r_todisut) |
| 3250 | tod += stdoff; |
| 3251 | if (rp->r_todisstd && !rp->r_isdst) |
| 3252 | tod += save; |
| 3253 | if (tod != 2 * SECSPERMIN * MINSPERHOUR) { |
| 3254 | *result++ = '/'; |
| 3255 | if (! stringoffset(result, tod)) |
| 3256 | return -1; |
no test coverage detected