Changeset 1788


Ignore:
Timestamp:
Jan 17, 2005, 9:07:48 AM (21 years ago)
Author:
bird
Message:

Added time64_t and a few 64-bit time functions for dealing better with over/underflows.

Location:
trunk/src/emx
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/include/emx/time.h

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1787 r1788  
    2020#define _TIME_T                         /* bird: EMX */
    2121#endif
     22
     23#ifndef _TIME64_T_DECLARED              /* bird: LIBC */
     24typedef __int64_t       time64_t;       /* bird: LIBC */
     25#define _TIME64_T_DECLARED              /* bird: LIBC */
     26#endif                                  /* bird: LIBC */
    2227
    2328struct tm;
     
    4550int _day (int, int, int);
    4651int _gmt2loc (time_t *);
     52int _gmt2loc64 (time64_t *p);
    4753int _loc2gmt (time_t *, int);
    48 /* struct tm *_gmtime (struct tm *, const time_t *); - use gmtime_r */
    49 /* struct tm *_localtime (struct tm *, const time_t *); - use localtime_r */
     54int _loc2gmt64 (time64_t *, int);
     55/* struct tm *_gmtime (struct tm *, const time_t *); - use _gmtime64_r */
     56/* struct tm *_localtime (struct tm *, const time_t *); - use _localtime64_r */
    5057unsigned long _mktime (struct tm *);
     58time64_t _mktime64 (struct tm *);
    5159void _compute_dst_table (void);
    5260
  • trunk/src/emx/include/time.h

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r1787 r1788  
    9393#endif
    9494
     95#ifndef _TIME64_T_DECLARED              /* bird: LIBC */
     96typedef __int64_t       time64_t;       /* bird: LIBC */
     97#define _TIME64_T_DECLARED              /* bird: LIBC */
     98#endif                                  /* bird: LIBC */
     99
    95100#if !defined(_SIZE_T_DECLARED) && !defined(_SIZE_T) /* bird: EMX */
    96101typedef __size_t        size_t;
     
    145150struct tm *gmtime(const time_t *);
    146151struct tm *localtime(const time_t *);
     152struct tm *_localtime64_r(const time64_t *, struct tm *); /* bird: LIBC */
    147153time_t mktime(struct tm *);
     154time64_t _mktime64(struct tm *); /* bird: LIBC  */
    148155size_t strftime(char * __restrict, size_t, const char * __restrict,
    149156    const struct tm * __restrict);
     
    165172char *ctime_r(const time_t *, char *);
    166173struct tm *gmtime_r(const time_t *, struct tm *);
     174struct tm *_gmtime64_r(const time64_t *, struct tm *); /* bird: LIBC */
    167175struct tm *localtime_r(const time_t *, struct tm *);
    168176#endif
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.92 to 1.93
    r1787 r1788  
    13731373    "__std_wcswidth" @1387
    13741374    "___libc_Back_fsUnlink" @1388
     1375    "__gmt2loc64" @1389
     1376    "__gmtime64_r" @1390
     1377    "__loc2gmt64" @1391
     1378    "__localtime64_r" @1392
     1379    "__mktime64" @1393
     1380    "___mktime64" @1394
  • trunk/src/emx/src/lib/time/gmtime.c

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r1787 r1788  
    44#include <stdlib.h>
    55#include <time.h>
     6#include <stdint.h>
    67#include <InnoTekLIBC/thread.h>
    78#include <emx/time.h>
    89
    9 struct tm *_STD(gmtime_r)(const time_t *t, struct tm *dst)
     10struct tm *_gmtime64_r(const time64_t *t, struct tm *dst)
    1011{
    1112    int days;
    1213    int rem;
     14    time64_t t1 = *t;
    1315
    1416    /* calc days relative to Epoch. */
    15     rem = *t;
    16     days = rem / (60*60*24);
    17     rem %= (60*60*24);
     17    days = t1 / (60*60*24);
     18    rem = t1 % (60*60*24);
    1819    while (rem < 0)
    1920    {
     
    6768}
    6869
     70struct tm *_STD(gmtime_r)(const time_t *t, struct tm *dst)
     71{
     72    time64_t t64 = *t;
     73    return _gmtime64_r(&t64, dst);
     74}
     75
    6976struct tm *_STD(gmtime)(const time_t *t)
    7077{
    71     __LIBC_PTHREAD pThrd = __libc_threadCurrent ();
    72     return gmtime_r (t, &pThrd->GmTimeAndLocalTimeBuf);
     78    __LIBC_PTHREAD pThrd = __libc_threadCurrent();
     79    return gmtime_r(t, &pThrd->GmTimeAndLocalTimeBuf);
    7380}
  • trunk/src/emx/src/lib/time/gmtloc.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1787 r1788  
    187187}
    188188
     189/**
     190 * Convert from gmt to local time.
     191 *
     192 * @returns 1 if dts.
     193 * @returns 0 if not dts.
     194 * @returns -1 on over/under flow.
     195 * @param   p   The time to convert.
     196 */
     197int _gmt2loc64 (time64_t *p)
     198{
     199    struct _dstswitch *sw;
     200    sw = find_switch ((time_t)*p); //fixme!
     201    time64_t t = *p - (_tzi.tz - sw->shift);
     202    if (_tzi.tz - sw->shift > 0 ? t > *p : t < *p)
     203        return -1;
     204    *p = t;
     205    return sw->shift != 0;
     206}
     207
    189208
    190209/* Note that this function returns -1 on error (overflow).
     
    265284    }
    266285}
     286
     287
     288/**
     289 * Convert from local time to gmt.
     290 *
     291 * @returns 1 if dts.
     292 * @returns 0 if not dts.
     293 * @returns -1 on over/under flow.
     294 * @param   p   The time to convert.
     295 */
     296int _loc2gmt64(time64_t *p, int is_dst)
     297{
     298    time64_t x;
     299    struct _dstswitch *sw;
     300    int count;
     301
     302    if (is_dst > 0)
     303    {
     304        /* Our caller says that *P is specified as DST.  Compute UTC
     305           from *P, assuming that daylight saving applies. */
     306
     307        x = *p + (_tzi.tz - _tzi.shift);
     308        if (_tzi.tz - _tzi.shift > 0 ? x < *p : x > *p)
     309            return -1;
     310        sw = find_switch (x);
     311        *p = x;
     312        return sw->shift != 0;
     313    }
     314    else if (is_dst == 0)
     315    {
     316        /* Our caller says that *P is specified as standard time.
     317           Compute UTC from *P, assuming that daylight saving does not
     318           apply. */
     319
     320        x = *p + _tzi.tz;
     321        if (_tzi.tz > 0 ? x < *p : x > *p)
     322            return -1;
     323        sw = find_switch (x);
     324        *p = x;
     325        return sw->shift != 0;
     326    }
     327    else
     328    {
     329        /* Our caller does not know whether *P is specified as DST or
     330           standard time.  Try to find out.  First try DST. */
     331
     332        count = 0;
     333        x = *p + _tzi.tz - _tzi.shift;
     334        if (!(_tzi.tz - _tzi.shift > 0 ? x < *p : x > *p))
     335        {
     336            sw = find_switch (x);
     337            if (sw->shift != 0)
     338            {
     339                *p = x;
     340                return 1;         /* DST */
     341            }
     342            ++count;
     343        }
     344
     345        x = *p + _tzi.tz;
     346        if (!(_tzi.tz > 0 ? x < *p : x > *p))
     347        {
     348            sw = find_switch (x);
     349            if (sw->shift == 0)
     350            {
     351                *p = x;
     352                return 0;         /* Not DST */
     353            }
     354            ++count;
     355        }
     356
     357        if (count != 2)
     358            return -1;              /* Overflow */
     359
     360        /* Assume that DST does not apply in the gap.  This makes moving
     361           into the gap from below work, but breaks moving into the gap
     362           from above.  The advantage of this choice is that ftime()
     363           works correctly in the gap if the clock is not adjusted. */
     364
     365        *p += _tzi.tz;
     366        return 0;                 /* Not DST */
     367    }
     368}
  • trunk/src/emx/src/lib/time/localtim.c

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r1787 r1788  
    66#include <emx/time.h>
    77
     8struct tm *_localtime64_r(const time64_t *t, struct tm *dst)
     9{
     10    if (!_tzset_flag)
     11        tzset();
     12    time64_t lt = *t;
     13    int isdst = _gmt2loc64(&lt);
     14    struct tm *p = _gmtime64_r(&lt, dst);
     15    p->tm_isdst = isdst;
     16    return p;
     17}
     18
     19struct tm *_STD(localtime_r)(const time_t *t, struct tm *dst)
     20{
     21    time64_t t64 = *t;
     22    return _localtime64_r(&t64, dst);
     23}
     24
    825struct tm *_STD(localtime)(const time_t *t)
    926{
     
    1229}
    1330
    14 struct tm *_STD(localtime_r)(const time_t *t, struct tm *dst)
    15 {
    16     time_t lt;
    17     int isdst;
    18     struct tm *p;
    19 
    20     if (!_tzset_flag) tzset();
    21     lt = *t;
    22     isdst = _gmt2loc(&lt);
    23     p = gmtime_r(&lt, dst);
    24     p->tm_isdst = isdst;
    25     return p;
    26 }
  • trunk/src/emx/src/lib/time/mktime.c

    • Property cvs2svn:cvs-rev changed from 1.7 to 1.8
    r1787 r1788  
    88time_t _STD(mktime) (struct tm *t)
    99{
    10   time_t t1, t2;
    11   struct tm tmp;
    12   int dst;
     10    time64_t t64 = _mktime64(t);
     11    time64_t t32 = _mktime64(t);
     12    if (t64 != t32)
     13        t32 = t64 > 0 ? TIME_T_MAX : TIME_T_MIN;
     14    return t32;
     15}
    1316
    14   if (!_tzset_flag) tzset ();
    1517
    16   /* _mktime() requires that tm_mon is in range.  The other members
    17      are not restricted. */
     18time64_t _mktime64(struct tm *t)
     19{
     20    time64_t t1, t2;
     21    struct tm tmp;
     22    int dst;
    1823
    19   if (t->tm_mon < 0)
     24    if (!_tzset_flag)
     25        tzset ();
     26
     27    /* mktime() requires that tm_mon is in range.  The other members
     28       are not restricted. */
     29
     30    if (t->tm_mon < 0)
    2031    {
    21       /* Avoid applying the `/' and `%' operators to negative numbers
    22          as the results are implementation-defined for negative
    23          numbers. */
     32        /* Avoid applying the `/' and `%' operators to negative numbers
     33           as the results are implementation-defined for negative
     34           numbers. */
    2435
    25       t->tm_year -= 1 + ((-t->tm_mon) / 12);
    26       t->tm_mon = 12 - ((-t->tm_mon) % 12);
     36        t->tm_year -= 1 + ((-t->tm_mon) / 12);
     37        t->tm_mon = 12 - ((-t->tm_mon) % 12);
    2738    }
    28   if (t->tm_mon >= 12)
     39    if (t->tm_mon >= 12)
    2940    {
    30       t->tm_year += (t->tm_mon / 12);
    31       t->tm_mon %= 12;
     41        t->tm_year += (t->tm_mon / 12);
     42        t->tm_mon %= 12;
    3243    }
    3344
    34   t1 = (time_t)_mktime (t);
    35   if (t1 == (time_t)-1)
    36     return (time_t)-1;
    37   dst = _loc2gmt (&t1, t->tm_isdst);
    38   if (dst == -1)
    39     return (time_t)-1;
    40   t2 = t1;
    41   dst = _gmt2loc (&t2);
    42   if (dst == -1)
    43     return (time_t)-1;
     45    t1 = (time_t)__mktime64(t);
     46    if (t1 == (time_t)-1)
     47        return -1;
     48    dst = _loc2gmt64(&t1, t->tm_isdst);
     49    if (dst == -1)
     50        return -1;
     51    t2 = t1;
     52    dst = _gmt2loc64(&t2);
     53    if (dst == -1)
     54        return -1;
    4455
    45   if (gmtime_r (&t2, &tmp) == NULL)
    46     return (time_t)-1;
    47   *t = tmp;
    48   t->tm_isdst = dst;
    49   return t1;
     56    if (_gmtime64_r(&t2, &tmp) == NULL)
     57        return -1;
     58    *t = tmp;
     59    t->tm_isdst = dst;
     60    return t1;
    5061}
    5162
     
    6879}
    6980
     81time64_t __mktime64(struct tm *t)
     82{
     83  time64_t x;
     84  time64_t r;
     85
     86  x = _day(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
     87  /* 719528 = day (1970, 1, 1) */
     88  r = (x - 719528) * 24 * 60 * 60;
     89
     90  /* This expression is not checked for overflow. */
     91  x = t->tm_sec
     92      + 60 * t->tm_min
     93      + 60 *60 * t->tm_hour;
     94
     95  r += x;
     96  return r;
     97}
     98
    7099/* mkstd.awk: NOUNDERSCORE(mktime) */
    71100unsigned long _mktime (struct tm *t)
Note: See TracChangeset for help on using the changeset viewer.