/* gmtime.c (emx+gcc) -- Copyright (c) 1990-1993 by Eberhard Mattes */

#include <sys/emx.h>
#include <stdlib.h>
#include <time.h>

static __inline__ int leap (unsigned int y)
{
  return (y % 4 != 0 ? 0 : y % 100 != 0 ? 1 : y % 400 != 0 ? 0 : 1);
}


struct tm *gmtime (const time_t *t)
{
#if defined (__MT__)
  struct _thread *tp = _thread ();
#define result (tp->_th_gmtime_buf)
#else
  static struct tm result;
#endif
  time_t t0, t1;
  _uldiv_t q;
  static int const mon_len[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

  t0 = *t;
  if (t0 == (time_t)(-1))
    return (NULL);
  q = _uldiv (t0, 60); result.tm_sec = q.rem; t0 = q.quot;
  q = _uldiv (t0, 60); result.tm_min = q.rem; t0 = q.quot;
  q = _uldiv (t0, 24); result.tm_hour = q.rem; t0 = q.quot;
  result.tm_wday = (t0+4) % 7;  /* 01-Jan-1970 was Thursday, ie, 4 */
  result.tm_year = 70;          /* 1970 */
  for (;;)
    {
      t1 = (leap (result.tm_year+1900) ? 366 : 365);
      if (t1 > t0)
        break;
      t0 -= t1;
      ++result.tm_year;
    }
  result.tm_mon = 0;
  result.tm_yday = t0;
  for (;;)
    {
      if (result.tm_mon == 1)       /* February */
        t1 = (leap (result.tm_year+1900) ? 29 : 28);
      else
        t1 = mon_len[result.tm_mon];
      if (t1 > t0)
        break;
      t0 -= t1;
      ++result.tm_mon;
    }
  result.tm_mday = t0 + 1;
  result.tm_isdst = 0;
  return (&result);
}
