aboutsummaryrefslogtreecommitdiffstats
path: root/main/stdtime
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2007-07-18 19:47:20 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2007-07-18 19:47:20 +0000
commit74c2948c2299773fd3816af43e06e3bdf714ba3a (patch)
tree540f82bac3e6105b6fc34cd4b4613c1756a7512b /main/stdtime
parentfd471b4a0cbb2abd7b4c8f30fee850cedefedaa1 (diff)
Merge in ast_strftime branch, which changes timestamps to be accurate to the microsecond, instead of only to the second
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@75706 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/stdtime')
-rw-r--r--main/stdtime/localtime.c183
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;
+}
+