diff options
Diffstat (limited to 'main/stdtime/localtime.c')
-rw-r--r-- | main/stdtime/localtime.c | 183 |
1 files changed, 116 insertions, 67 deletions
diff --git a/main/stdtime/localtime.c b/main/stdtime/localtime.c index 18cd3d7d8..4426feb97 100644 --- a/main/stdtime/localtime.c +++ b/main/stdtime/localtime.c @@ -180,25 +180,25 @@ static const char * getsecs P((const char * strp, long * secsp)); static const char * getoffset P((const char * strp, long * offsetp)); static const char * getrule P((const char * strp, struct rule * rulep)); static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp, const char * zone)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp, const char * zone)); +static void gmtsub P((const struct timeval * timep, long offset, + struct ast_tm * tmp, const char * zone)); +static void localsub P((const struct timeval * timep, long offset, + struct ast_tm * tmp, const char * zone)); static int increment_overflow P((int * number, int delta)); static int normalize_overflow P((int * tensptr, int * unitsptr, int base)); -static time_t time1 P((struct tm * tmp, - void(*funcp) P((const time_t *, - long, struct tm *, const char*)), +static time_t time1 P((struct ast_tm * tmp, + void(*funcp) P((const struct timeval *, + long, struct ast_tm *, const char *)), long offset, const char * zone)); -static time_t time2 P((struct tm *tmp, - void(*funcp) P((const time_t *, - long, struct tm*, const char*)), +static time_t time2 P((struct ast_tm *tmp, + void(*funcp) P((const struct timeval *, + long, struct ast_tm *, const char *)), long offset, int * okayp, const char * zone)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); +static void timesub P((const struct timeval * timep, long offset, + const struct state * sp, struct ast_tm *tmp)); +static int tmcomp P((const struct ast_tm *atmp, + const struct ast_tm * btmp)); static time_t transtime P((time_t janfirst, int year, const struct rule * rulep, long offset)); static int tzload P((const char * name, struct state * sp)); @@ -982,15 +982,16 @@ ast_tzset P((const char *name)) /*ARGSUSED*/ static void localsub(timep, offset, tmp, zone) -const time_t * const timep; +const struct timeval * const timep; const long offset; -struct tm * const tmp; +struct ast_tm * const tmp; const char * const zone; { register struct state * sp; register const struct ttinfo * ttisp; register int i; - const time_t t = *timep; + struct timeval t; + memcpy(&t, timep, sizeof(t)); sp = lclptr; /* Find the right zone record */ @@ -1019,7 +1020,7 @@ const char * const zone; gmtsub(timep, offset, tmp, zone); return; } - if (sp->timecnt == 0 || t < sp->ats[0]) { + if (sp->timecnt == 0 || t.tv_sec < sp->ats[0]) { i = 0; while (sp->ttis[i].tt_isdst) if (++i >= sp->typecnt) { @@ -1028,7 +1029,7 @@ const char * const zone; } } else { for (i = 1; i < sp->timecnt; ++i) - if (t < sp->ats[i]) + if (t.tv_sec < sp->ats[i]) break; i = sp->types[i - 1]; } @@ -1045,12 +1046,13 @@ const char * const zone; #ifdef TM_ZONE tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; #endif /* defined TM_ZONE */ + tmp->tm_usec = timep->tv_usec; } -struct tm * +struct ast_tm * ast_localtime(timep, p_tm, zone) -const time_t * const timep; -struct tm *p_tm; +const struct timeval * const timep; +struct ast_tm *p_tm; const char * const zone; { #ifdef _THREAD_SAFE @@ -1070,9 +1072,9 @@ const char * const zone; static void gmtsub(timep, offset, tmp, zone) -const time_t * const timep; +const struct timeval * const timep; const long offset; -struct tm * const tmp; +struct ast_tm * const tmp; const char * const zone; { #ifdef _THREAD_SAFE @@ -1104,10 +1106,10 @@ const char * const zone; static void timesub(timep, offset, sp, tmp) -const time_t * const timep; +const struct timeval * const timep; const long offset; register const struct state * const sp; -register struct tm * const tmp; +register struct ast_tm * const tmp; { register const struct lsinfo * lp; register long days; @@ -1124,8 +1126,8 @@ register struct tm * const tmp; i = (sp == NULL) ? 0 : sp->leapcnt; while (--i >= 0) { lp = &sp->lsis[i]; - if (*timep >= lp->ls_trans) { - if (*timep == lp->ls_trans) { + if (timep->tv_sec >= lp->ls_trans) { + if (timep->tv_sec == lp->ls_trans) { hit = ((i == 0 && lp->ls_corr > 0) || lp->ls_corr > sp->lsis[i - 1].ls_corr); if (hit) @@ -1142,10 +1144,10 @@ register struct tm * const tmp; break; } } - days = *timep / SECSPERDAY; - rem = *timep % SECSPERDAY; + days = timep->tv_sec / SECSPERDAY; + rem = timep->tv_sec % SECSPERDAY; #ifdef mc68k - if (*timep == 0x80000000) { + if (timep->tv_sec == 0x80000000) { /* ** A 3B1 muffs the division on the most negative number. */ @@ -1196,28 +1198,16 @@ register struct tm * const tmp; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ + tmp->tm_usec = timep->tv_usec; } char * -ast_ctime(timep) -const time_t * const timep; -{ -/* -** Section 4.12.3.2 of X3.159-1989 requires that -** The ctime funciton converts the calendar time pointed to by timer -** to local time in the form of a string. It is equivalent to -** asctime(localtime(timer)) -*/ - return asctime(localtime(timep)); -} - -char * -ast_ctime_r(timep, buf) -const time_t * const timep; +ast_ctime(timep, buf) +const struct timeval * const timep; char *buf; { - struct tm tm; - return asctime_r(ast_localtime(timep, &tm, NULL), buf); + struct ast_tm tm; + return asctime_r((struct tm *)ast_localtime(timep, &tm, NULL), buf); } /* @@ -1267,8 +1257,8 @@ const int base; static int tmcomp(atmp, btmp) -register const struct tm * const atmp; -register const struct tm * const btmp; +register const struct ast_tm * const atmp; +register const struct ast_tm * const btmp; { register int result; @@ -1283,8 +1273,8 @@ register const struct tm * const btmp; static time_t time2(tmp, funcp, offset, okayp, zone) -struct tm * const tmp; -void (* const funcp) P((const time_t*, long, struct tm*, const char*)); +struct ast_tm * const tmp; +void (* const funcp) P((const struct timeval *, long, struct ast_tm*, const char*)); const long offset; int * const okayp; const char * const zone; @@ -1294,9 +1284,9 @@ const char * const zone; register int bits; register int i, j ; register int saved_seconds; - time_t newt; - time_t t; - struct tm yourtm, mytm; + struct timeval newt = { 0, 0 }; + struct timeval t = { 0, 0 }; + struct ast_tm yourtm, mytm; *okayp = FALSE; yourtm = *tmp; @@ -1364,7 +1354,7 @@ const char * const zone; ** assuming two's complement arithmetic. ** If time_t is unsigned, then (1 << bits) is just above the median. */ - t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); + t.tv_sec = 0; for ( ; ; ) { (*funcp)(&t, offset, &mytm, zone); dir = tmcomp(&mytm, &yourtm); @@ -1372,10 +1362,10 @@ const char * const zone; if (bits-- < 0) return WRONG; if (bits < 0) - --t; /* may be needed if new t is minimal */ + --t.tv_sec; /* may be needed if new t is minimal */ else if (dir > 0) - t -= ((time_t) 1) << bits; - else t += ((time_t) 1) << bits; + t.tv_sec -= ((time_t) 1) << bits; + else t.tv_sec += ((time_t) 1) << bits; continue; } if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) @@ -1400,7 +1390,7 @@ const char * const zone; for (j = sp->typecnt - 1; j >= 0; --j) { if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) continue; - newt = t + sp->ttis[j].tt_gmtoff - + newt.tv_sec = t.tv_sec + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff; (*funcp)(&newt, offset, &mytm, zone); if (tmcomp(&mytm, &yourtm) != 0) @@ -1417,19 +1407,19 @@ const char * const zone; return WRONG; } label: - newt = t + saved_seconds; - if ((newt < t) != (saved_seconds < 0)) + newt.tv_sec = t.tv_sec + saved_seconds; + if ((newt.tv_sec < t.tv_sec) != (saved_seconds < 0)) return WRONG; - t = newt; + t.tv_sec = newt.tv_sec; (*funcp)(&t, offset, tmp, zone); *okayp = TRUE; - return t; + return t.tv_sec; } static time_t time1(tmp, funcp, offset, zone) -struct tm * const tmp; -void (* const funcp) P((const time_t *, long, struct tm *, const char*)); +struct ast_tm * const tmp; +void (* const funcp) P((const struct timeval *, long, struct ast_tm *, const char*)); const long offset; const char * const zone; { @@ -1489,7 +1479,7 @@ const char * const zone; time_t ast_mktime(tmp,zone) -struct tm * const tmp; +struct ast_tm * const tmp; const char * const zone; { time_t mktime_return_value; @@ -1504,3 +1494,62 @@ const char * const zone; return(mktime_return_value); } +int ast_strftime(char *buf, size_t len, const char *tmp, const struct ast_tm *tm) +{ + size_t fmtlen = strlen(tmp) + 1; + char *format = ast_calloc(1, fmtlen), *fptr = format, *newfmt; + int decimals = -1, i, res; + long fraction; + + if (!format) + return -1; + for (; *tmp; tmp++) { + if (*tmp == '%') { + switch (tmp[1]) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + if (tmp[2] != 'q') + goto defcase; + decimals = tmp[1] - '0'; + tmp++; + /* Fall through */ + case 'q': /* Milliseconds */ + if (decimals == -1) + decimals = 3; + + /* Juggle some memory to fit the item */ + newfmt = ast_realloc(format, fmtlen + decimals); + if (!newfmt) { + ast_free(format); + return -1; + } + fptr = fptr - format + newfmt; + format = newfmt; + fmtlen += decimals; + + /* Reduce the fraction of time to the accuracy needed */ + for (i = 6, fraction = tm->tm_usec; i > decimals; i--) + fraction /= 10; + fptr += sprintf(fptr, "%0*ld", decimals, fraction); + + /* Reset, in case more than one 'q' specifier exists */ + decimals = -1; + tmp++; + break; + default: + goto defcase; + } + } else +defcase: *fptr++ = *tmp; + } + *fptr = '\0'; +#undef strftime + res = (int)strftime(buf, len, format, (struct tm *)tm); + ast_free(format); + return res; +} + |