- val = tm->tm_year + 1900;
- fmt = "%04d";
- goto number;
- case 'z':
- if (tm->tm_isdst < 0) continue;
- val = timezone + (tm->tm_isdst) ? __dst_offset : 0;
- l += snprintf(s+l, n-l, "%+02d%02d", val/60, abs(val%60));
- continue;
- case 'Z':
- if (tm->tm_isdst < 0 || !tzname[0] || !tzname[0][0])
- continue;
- l += snprintf(s+l, n-l, "%s", tzname[!!tm->tm_isdst]);
- continue;
- }
- default:
- return NULL;
+ dest = &tm->tm_year;
+ if (w<0) w=4;
+ adj = 1900;
+ goto numeric_digits;
+ case '%':
+ if (*s++ != '%') return 0;
+ break;
+ numeric_range:
+ if (!isdigit(*s)) return 0;
+ *dest = 0;
+ for (i=1; i<=min+range && isdigit(*s); i*=10)
+ *dest = *dest * 10 + *s++ - '0';
+ if (*dest - min >= (unsigned)range) return 0;
+ *dest -= adj;
+ switch((char *)dest - (char *)tm) {
+ case offsetof(struct tm, tm_yday):
+ ;
+ }
+ goto update;
+ numeric_digits:
+ neg = 0;
+ if (*s == '+') s++;
+ else if (*s == '-') neg=1, s++;
+ if (!isdigit(*s)) return 0;
+ for (*dest=i=0; i<w && isdigit(*s); i++)
+ *dest = *dest * 10 + *s++ - '0';
+ if (neg) *dest = -*dest;
+ *dest -= adj;
+ goto update;
+ symbolic_range:
+ for (i=2*range-1; i>=0; i--) {
+ ex = nl_langinfo(min+i);
+ len = strlen(ex);
+ if (strncasecmp(s, ex, len)) continue;
+ s += len;
+ *dest = i % range;
+ break;
+ }
+ if (i<0) return 0;
+ goto update;
+ update:
+ //FIXME
+ ;