]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/Time/Time.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / LibC / Time / Time.c
diff --git a/StdLib/LibC/Time/Time.c b/StdLib/LibC/Time/Time.c
deleted file mode 100644 (file)
index 6d83986..0000000
+++ /dev/null
@@ -1,765 +0,0 @@
-/**\r
-  Definitions and Implementation for <time.h>.\r
-\r
-  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials are licensed and made available under\r
-  the terms and conditions of the BSD License that accompanies this distribution.\r
-  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-  Portions derived from the NIH time zone package file, localtime.c,\r
-  which contains the following notice:\r
-\r
-    This file is in the public domain, so clarified as of\r
-    1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).\r
-\r
-  NetBSD: localtime.c,v 1.39 2006/03/22 14:01:30 christos Exp\r
-**/\r
-#include  <Uefi.h>\r
-#include  <Library/UefiLib.h>\r
-#include  <Library/TimerLib.h>\r
-#include  <Library/BaseLib.h>\r
-#include  <Library/UefiRuntimeServicesTableLib.h>\r
-//#include  <Library/UefiRuntimeLib.h>\r
-\r
-#include  <LibConfig.h>\r
-\r
-#include  <errno.h>\r
-#include  <limits.h>\r
-#include  <time.h>\r
-#include  <reentrant.h>\r
-#include  "tzfile.h"\r
-#include  "TimeVals.h"\r
-#include  <MainData.h>\r
-#include  <extern.h>      // Library/include/extern.h: Private to implementation\r
-\r
-#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */\r
-// Keep compiler quiet about casting from function to data pointers\r
-#pragma warning ( disable : 4054 )\r
-#endif  /* defined(_MSC_VER) */\r
-\r
-/* #######################  Private Data  ################################# */\r
-\r
-#if 0\r
-static EFI_TIME TimeBuffer;\r
-\r
-  static  UINT16   MonthOffs[12] = {\r
-     00,\r
-     31,   59,   90,  120,\r
-    151,  181,  212,  243,\r
-    273,  304,  334\r
-  };\r
-  static  clock_t   y2kOffs = 730485;\r
-#endif\r
-\r
-const int  mon_lengths[2][MONSPERYEAR] = {\r
-  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },\r
-  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }\r
-};\r
-\r
-const int  year_lengths[2] = {\r
-  DAYSPERNYEAR, DAYSPERLYEAR\r
-};\r
-\r
-\r
-static const char *wday_name[7] = {\r
-  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"\r
-};\r
-\r
-static const char *mon_name[12] = {\r
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"\r
-};\r
-\r
-static int    gmt_is_set;\r
-\r
-/* ###############  Implementation Functions  ############################ */\r
-// Forward reference\r
-static void\r
-localsub(const time_t * const timep, const long   offset, struct tm * const tmp);\r
-\r
-clock_t\r
-__getCPS(void)\r
-{\r
-  return gMD->ClocksPerSecond;\r
-}\r
-\r
-static void\r
-timesub(\r
-  const time_t        * const timep,\r
-  const long                  offset,\r
-  const struct state  * const sp,\r
-        struct tm     * const tmp\r
-  )\r
-{\r
-  const struct lsinfo *  lp;\r
-  time_t /*INTN*/     days;\r
-  time_t /*INTN*/     rem;\r
-  time_t /*INTN*/      y;\r
-  int      yleap;\r
-  const int *    ip;\r
-  time_t /*INTN*/     corr;\r
-  int      hit;\r
-  int      i;\r
-\r
-  corr = 0;\r
-  hit = 0;\r
-#ifdef ALL_STATE\r
-  i = (sp == NULL) ? 0 : sp->leapcnt;\r
-#endif /* defined ALL_STATE */\r
-#ifndef ALL_STATE\r
-  i = sp->leapcnt;\r
-#endif /* State Farm */\r
-  while (--i >= 0) {\r
-    lp = &sp->lsis[i];\r
-    if (*timep >= lp->ls_trans) {\r
-      if (*timep == lp->ls_trans) {\r
-        hit = ((i == 0 && lp->ls_corr > 0) ||\r
-               lp->ls_corr > sp->lsis[i - 1].ls_corr);\r
-        if (hit)\r
-          while (i > 0                                                &&\r
-                 sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&\r
-                 sp->lsis[i].ls_corr  == sp->lsis[i - 1].ls_corr  + 1 )\r
-          {\r
-            ++hit;\r
-            --i;\r
-          }\r
-      }\r
-      corr = lp->ls_corr;\r
-      break;\r
-    }\r
-  }\r
-  days = *timep / SECSPERDAY;\r
-  rem = *timep % SECSPERDAY;\r
-  rem += (offset - corr);\r
-  while (rem < 0) {\r
-    rem += SECSPERDAY;\r
-    --days;\r
-  }\r
-  while (rem >= SECSPERDAY) {\r
-    rem -= SECSPERDAY;\r
-    ++days;\r
-  }\r
-  tmp->tm_hour = (int) (rem / SECSPERHOUR);\r
-  rem = rem % SECSPERHOUR;\r
-  tmp->tm_min = (int) (rem / SECSPERMIN);\r
-  /*\r
-  ** A positive leap second requires a special\r
-  ** representation.  This uses "... ??:59:60" et seq.\r
-  */\r
-  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;\r
-  tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);\r
-  if (tmp->tm_wday < 0)\r
-    tmp->tm_wday += DAYSPERWEEK;\r
-  y = EPOCH_YEAR;\r
-  while (days < 0 || days >= (LONG32) year_lengths[yleap = isleap(y)]) {\r
-    time_t /*INTN*/  newy;\r
-\r
-    newy = (y + days / DAYSPERNYEAR);\r
-    if (days < 0)\r
-      --newy;\r
-    days -= (newy - y) * DAYSPERNYEAR +\r
-      LEAPS_THRU_END_OF(newy - 1) -\r
-      LEAPS_THRU_END_OF(y - 1);\r
-    y = newy;\r
-  }\r
-  tmp->tm_year = (int)(y - TM_YEAR_BASE);\r
-  tmp->tm_yday = (int) days;\r
-  ip = mon_lengths[yleap];\r
-  for (tmp->tm_mon = 0; days >= (LONG32) ip[tmp->tm_mon]; ++(tmp->tm_mon))\r
-    days = days - (LONG32) ip[tmp->tm_mon];\r
-  tmp->tm_mday = (int) (days + 1);\r
-  tmp->tm_isdst = 0;\r
-#ifdef TM_GMTOFF\r
-  tmp->TM_GMTOFF = offset;\r
-#endif /* defined TM_GMTOFF */\r
-}\r
-\r
-/* ###############  Time Manipulation Functions  ########################## */\r
-\r
-/**\r
-**/\r
-double\r
-difftime(time_t time1, time_t time0)\r
-{\r
-  return (double)(time1 - time0);\r
-}\r
-\r
-/*\r
-** Adapted from code provided by Robert Elz, who writes:\r
-**  The "best" way to do mktime I think is based on an idea of Bob\r
-**  Kridle's (so its said...) from a long time ago.\r
-**  [kridle@xinet.com as of 1996-01-16.]\r
-**  It does a binary search of the time_t space.  Since time_t's are\r
-**  just 32 bits, its a max of 32 iterations (even at 64 bits it\r
-**  would still be very reasonable).\r
-*/\r
-\r
-#ifndef WRONG\r
-#define WRONG (-1)\r
-#endif /* !defined WRONG */\r
-\r
-/*\r
-** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).\r
-*/\r
-\r
-static int\r
-increment_overflow(int * number, int delta)\r
-{\r
-  int number0;\r
-\r
-  number0 = *number;\r
-  *number += delta;\r
-  return (*number < number0) != (delta < 0);\r
-}\r
-\r
-static int\r
-normalize_overflow(int * const tensptr, int * const unitsptr, const int base)\r
-{\r
-  register int  tensdelta;\r
-\r
-  tensdelta = (*unitsptr >= 0)  ?\r
-              (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);\r
-  *unitsptr -= tensdelta * base;\r
-  return increment_overflow(tensptr, tensdelta);\r
-}\r
-\r
-static int\r
-tmcomp(const struct tm * const atmp, const struct tm * const btmp)\r
-{\r
-  register int  result;\r
-\r
-  if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&\r
-      (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&\r
-      (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&\r
-      (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&\r
-      (result = (atmp->tm_min - btmp->tm_min)) == 0)\r
-    result = atmp->tm_sec - btmp->tm_sec;\r
-  return result;\r
-}\r
-\r
-static time_t\r
-time2sub(\r
-  struct tm * const tmp,\r
-  void (* const funcp)(const time_t*, long, struct tm*),\r
-  const long offset,\r
-  int * const okayp,\r
-  const int do_norm_secs\r
-  )\r
-{\r
-  register const struct state * sp;\r
-  register int                  dir;\r
-  register int                  bits;\r
-  register int                  i, j ;\r
-  register int                  saved_seconds;\r
-  time_t                        newt;\r
-  time_t                        t;\r
-  struct tm                     yourtm, mytm;\r
-\r
-  *okayp = FALSE;\r
-  yourtm = *tmp;    // Create a copy of tmp\r
-  if (do_norm_secs) {\r
-    if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,\r
-                           SECSPERMIN))\r
-      return WRONG;\r
-  }\r
-  if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))\r
-    return WRONG;\r
-  if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))\r
-    return WRONG;\r
-  if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))\r
-    return WRONG;\r
-  /*\r
-  ** Turn yourtm.tm_year into an actual year number for now.\r
-  ** It is converted back to an offset from TM_YEAR_BASE later.\r
-  */\r
-  if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))\r
-    return WRONG;\r
-  while (yourtm.tm_mday <= 0) {\r
-    if (increment_overflow(&yourtm.tm_year, -1))\r
-      return WRONG;\r
-    i = yourtm.tm_year + (1 < yourtm.tm_mon);\r
-    yourtm.tm_mday += year_lengths[isleap(i)];\r
-  }\r
-  while (yourtm.tm_mday > DAYSPERLYEAR) {\r
-    i = yourtm.tm_year + (1 < yourtm.tm_mon);\r
-    yourtm.tm_mday -= year_lengths[isleap(i)];\r
-    if (increment_overflow(&yourtm.tm_year, 1))\r
-      return WRONG;\r
-  }\r
-  for ( ; ; ) {\r
-    i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];\r
-    if (yourtm.tm_mday <= i)\r
-      break;\r
-    yourtm.tm_mday -= i;\r
-    if (++yourtm.tm_mon >= MONSPERYEAR) {\r
-      yourtm.tm_mon = 0;\r
-      if (increment_overflow(&yourtm.tm_year, 1))\r
-        return WRONG;\r
-    }\r
-  }\r
-  if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))\r
-    return WRONG;\r
-  if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)\r
-    saved_seconds = 0;\r
-  else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {\r
-    /*\r
-    ** We can't set tm_sec to 0, because that might push the\r
-    ** time below the minimum representable time.\r
-    ** Set tm_sec to 59 instead.\r
-    ** This assumes that the minimum representable time is\r
-    ** not in the same minute that a leap second was deleted from,\r
-    ** which is a safer assumption than using 58 would be.\r
-    */\r
-    if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))\r
-      return WRONG;\r
-    saved_seconds = yourtm.tm_sec;\r
-    yourtm.tm_sec = SECSPERMIN - 1;\r
-  } else {\r
-    saved_seconds = yourtm.tm_sec;\r
-    yourtm.tm_sec = 0;\r
-  }\r
-  /*\r
-  ** Divide the search space in half\r
-  ** (this works whether time_t is signed or unsigned).\r
-  */\r
-  bits = TYPE_BIT(time_t) - 1;\r
-  /*\r
-  ** Set t to the midpoint of our binary search.\r
-  **\r
-  ** If time_t is signed, then 0 is just above the median,\r
-  ** assuming two's complement arithmetic.\r
-  ** If time_t is unsigned, then (1 << bits) is just above the median.\r
-  */\r
-  t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);\r
-  for ( ; ; ) {\r
-    (*funcp)(&t, offset, &mytm);    // Convert t to broken-down time in mytm\r
-    dir = tmcomp(&mytm, &yourtm);   // Is mytm larger, equal, or less than yourtm?\r
-    if (dir != 0) {                 // If mytm != yourtm...\r
-      if (bits-- < 0)                   // If we have exhausted all the bits..\r
-        return WRONG;                       // Return that we failed\r
-      if (bits < 0)                     // If on the last bit...\r
-        --t; /* may be needed if new t is minimal */\r
-      else if (dir > 0)                 // else if mytm > yourtm...\r
-        t -= ((time_t) 1) << bits;          // subtract half the remaining time-space\r
-      else  t += ((time_t) 1) << bits;      // otherwise add half the remaining time-space\r
-      continue;                     // Repeat for the next half\r
-    }\r
-    if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)\r
-      break;\r
-    /*\r
-    ** Right time, wrong type.\r
-    ** Hunt for right time, right type.\r
-    ** It's okay to guess wrong since the guess\r
-    ** gets checked.\r
-    */\r
-    /*\r
-    ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.\r
-    */\r
-    sp = (const struct state *)\r
-      (((void *) funcp == (void *) localsub) ?\r
-       lclptr : gmtptr);\r
-#ifdef ALL_STATE\r
-    if (sp == NULL)\r
-      return WRONG;\r
-#endif /* defined ALL_STATE */\r
-    for (i = sp->typecnt - 1; i >= 0; --i) {\r
-      if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)\r
-        continue;\r
-      for (j = sp->typecnt - 1; j >= 0; --j) {\r
-        if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)\r
-          continue;\r
-        newt = t + sp->ttis[j].tt_gmtoff -\r
-          sp->ttis[i].tt_gmtoff;\r
-        (*funcp)(&newt, offset, &mytm);\r
-        if (tmcomp(&mytm, &yourtm) != 0)\r
-          continue;\r
-        if (mytm.tm_isdst != yourtm.tm_isdst)\r
-          continue;\r
-        /*\r
-        ** We have a match.\r
-        */\r
-        t = newt;\r
-        goto label;\r
-      }\r
-    }\r
-    return WRONG;\r
-  }\r
-  label:\r
-  newt = t + saved_seconds;\r
-  if ((newt < t) != (saved_seconds < 0))\r
-    return WRONG;\r
-  t = newt;\r
-  (*funcp)(&t, offset, tmp);\r
-  *okayp = TRUE;\r
-  return t;\r
-}\r
-\r
-time_t\r
-time2(struct tm * const tmp, void (* const funcp)(const time_t*, long, struct tm*),\r
-      const long offset, int * const okayp)\r
-{\r
-  time_t  t;\r
-\r
-  /*\r
-  ** First try without normalization of seconds\r
-  ** (in case tm_sec contains a value associated with a leap second).\r
-  ** If that fails, try with normalization of seconds.\r
-  */\r
-  t = time2sub(tmp, funcp, offset, okayp, FALSE);\r
-  return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);\r
-}\r
-\r
-static time_t\r
-time1(\r
-  struct tm * const tmp,\r
-  void (* const funcp)(const time_t *, long, struct tm *),\r
-  const long offset\r
-  )\r
-{\r
-  register time_t               t;\r
-  register const struct state * sp;\r
-  register int                  samei, otheri;\r
-  register int                  sameind, otherind;\r
-  register int                  i;\r
-  register int                  nseen;\r
-  int                           seen[TZ_MAX_TYPES];\r
-  int                           types[TZ_MAX_TYPES];\r
-  int                           okay;\r
-\r
-  if (tmp->tm_isdst > 1)\r
-    tmp->tm_isdst = 1;\r
-  t = time2(tmp, funcp, offset, &okay);\r
-#ifdef PCTS\r
-  /*\r
-  ** PCTS code courtesy Grant Sullivan (grant@osf.org).\r
-  */\r
-  if (okay)\r
-    return t;\r
-  if (tmp->tm_isdst < 0)\r
-    tmp->tm_isdst = 0;  /* reset to std and try again */\r
-#endif /* defined PCTS */\r
-#ifndef PCTS\r
-  if (okay || tmp->tm_isdst < 0)\r
-    return t;\r
-#endif /* !defined PCTS */\r
-  /*\r
-  ** We're supposed to assume that somebody took a time of one type\r
-  ** and did some math on it that yielded a "struct tm" that's bad.\r
-  ** We try to divine the type they started from and adjust to the\r
-  ** type they need.\r
-  */\r
-  /*\r
-  ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.\r
-  */\r
-  sp = (const struct state *) (((void *) funcp == (void *) localsub) ?\r
-                               lclptr : gmtptr);\r
-#ifdef ALL_STATE\r
-  if (sp == NULL)\r
-    return WRONG;\r
-#endif /* defined ALL_STATE */\r
-  for (i = 0; i < sp->typecnt; ++i)\r
-    seen[i] = FALSE;\r
-  nseen = 0;\r
-    for (i = sp->timecnt - 1; i >= 0; --i)\r
-      if (!seen[sp->types[i]]) {\r
-        seen[sp->types[i]] = TRUE;\r
-        types[nseen++] = sp->types[i];\r
-      }\r
-    for (sameind = 0; sameind < nseen; ++sameind) {\r
-      samei = types[sameind];\r
-      if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)\r
-        continue;\r
-      for (otherind = 0; otherind < nseen; ++otherind) {\r
-        otheri = types[otherind];\r
-        if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)\r
-          continue;\r
-        tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff -\r
-                             sp->ttis[samei].tt_gmtoff);\r
-        tmp->tm_isdst = !tmp->tm_isdst;\r
-        t = time2(tmp, funcp, offset, &okay);\r
-        if (okay)\r
-          return t;\r
-        tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff -\r
-                             sp->ttis[samei].tt_gmtoff);\r
-        tmp->tm_isdst = !tmp->tm_isdst;\r
-      }\r
-    }\r
-    return WRONG;\r
-}\r
-\r
-/** The mktime function converts the broken-down time, expressed as local time,\r
-    in the structure pointed to by timeptr into a calendar time value with the\r
-    same encoding as that of the values returned by the time function.  The\r
-    original values of the tm_wday and tm_yday components of the structure are\r
-    ignored, and the original values of the other components are not restricted\r
-    to the ranges indicated above.  Thus, a positive or zero value for tm_isdst\r
-    causes the mktime function to presume initially that Daylight Saving Time,\r
-    respectively, is or is not in effect for the specified time. A negative\r
-    value causes it to attempt to determine whether Daylight Saving Time is in\r
-    effect for the specified time.  On successful completion, the values of the\r
-    tm_wday and tm_yday components of the structure are set appropriately, and\r
-    the other components are set to represent the specified calendar time, but\r
-    with their values forced to the ranges indicated above; the final value of\r
-    tm_mday is not set until tm_mon and tm_year are determined.\r
-\r
-    @return   The mktime function returns the specified calendar time encoded\r
-              as a value of type time_t.  If the calendar time cannot be\r
-              represented, the function returns the value (time_t)(-1).\r
-**/\r
-time_t\r
-mktime(struct tm *timeptr)\r
-{\r
-  /* From NetBSD */\r
-  time_t result;\r
-\r
-  rwlock_wrlock(&lcl_lock);\r
-  tzset();\r
-  result = time1(timeptr, &localsub, 0L);\r
-  rwlock_unlock(&lcl_lock);\r
-  return (result);\r
-}\r
-\r
-/** The time function determines the current calendar time.  The encoding of\r
-    the value is unspecified.\r
-\r
-    @return   The time function returns the implementation's best approximation\r
-              to the current calendar time.  The value (time_t)(-1) is returned\r
-              if the calendar time is not available.  If timer is not a null\r
-              pointer, the return value is also assigned to the object it\r
-              points to.\r
-**/\r
-time_t\r
-time(time_t *timer)\r
-{\r
-  time_t      CalTime;\r
-  EFI_STATUS  Status;\r
-  EFI_TIME   *ET;\r
-  struct tm  *BT;\r
-\r
-  ET = &gMD->TimeBuffer;\r
-  BT = &gMD->BDTime;\r
-\r
-  // Get EFI Time\r
-  Status = gRT->GetTime( ET, NULL);\r
-//  Status = EfiGetTime( ET, NULL);\r
-  EFIerrno = Status;\r
-  if( Status != RETURN_SUCCESS) {\r
-    return (time_t)-1;\r
-  }\r
-\r
-  // Convert EFI time to broken-down time.\r
-  Efi2Tm( ET, BT);\r
-\r
-  // Convert to time_t\r
-  CalTime  =  mktime(&gMD->BDTime);\r
-\r
-  if( timer != NULL) {\r
-    *timer = CalTime;\r
-  }\r
-  return CalTime;   // Return calendar time in microseconds\r
-}\r
-\r
-/** The clock function determines the processor time used.\r
-\r
-    @return   The clock function returns the implementation's best\r
-              approximation to the processor time used by the program since the\r
-              beginning of an implementation-defined era related only to the\r
-              program invocation.  To determine the time in seconds, the value\r
-              returned by the clock function should be divided by the value of\r
-              the macro CLOCKS_PER_SEC.  If the processor time used is not\r
-              available or its value cannot be represented, the function\r
-              returns the value (clock_t)(-1).\r
-**/\r
-clock_t\r
-clock(void)\r
-{\r
-  clock_t   retval;\r
-  time_t    temp;\r
-\r
-  temp = time(NULL);\r
-  retval = ((clock_t)((UINT32)temp)) - gMD->AppStartTime;\r
-  return retval;\r
-}\r
-\r
-/* #################  Time Conversion Functions  ########################## */\r
-/*\r
-    Except for the strftime function, these functions each return a pointer to\r
-    one of two types of static objects: a broken-down time structure or an\r
-    array of char.  Execution of any of the functions that return a pointer to\r
-    one of these object types may overwrite the information in any object of\r
-    the same type pointed to by the value returned from any previous call to\r
-    any of them.  The implementation shall behave as if no other library\r
-    functions call these functions.\r
-*/\r
-\r
-/** The asctime function converts the broken-down time in the structure pointed\r
-    to by timeptr into a string in the form\r
-      Sun Sep 16 01:03:52 1973\n\0\r
-    using the equivalent of the following algorithm.\r
-\r
-      char *asctime(const struct tm *timeptr)\r
-      {\r
-        static const char wday_name[7][3] = {\r
-          "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"\r
-        };\r
-        static const char mon_name[12][3] = {\r
-          "Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
-          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"\r
-        };\r
-        static char result[26];\r
-        sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",\r
-                wday_name[timeptr->tm_wday],\r
-                mon_name[timeptr->tm_mon],\r
-                timeptr->tm_mday, timeptr->tm_hour,\r
-                timeptr->tm_min, timeptr->tm_sec,\r
-                1900 + timeptr->tm_year);\r
-        return result;\r
-      }\r
-    @return   The asctime function returns a pointer to the string.\r
-**/\r
-char *\r
-asctime(const struct tm *timeptr)\r
-{\r
-  register const char * wn;\r
-  register const char * mn;\r
-\r
-  if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)\r
-    wn = "???";\r
-  else  wn = wday_name[timeptr->tm_wday];\r
-  if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)\r
-    mn = "???";\r
-  else  mn = mon_name[timeptr->tm_mon];\r
-  /*\r
-  ** The X3J11-suggested format is\r
-  **  "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"\r
-  ** Since the .2 in 02.2d is ignored, we drop it.\r
-  */\r
-  (void)snprintf(gMD->ASasctime,\r
-                 sizeof (char[ASCTIME_BUFLEN]),\r
-                 "%.3s %.3s%3d %02d:%02d:%02d %d\r\n",    // explicit CRLF for EFI\r
-                 wn, mn,\r
-                 timeptr->tm_mday, timeptr->tm_hour,\r
-                 timeptr->tm_min, timeptr->tm_sec,\r
-                 TM_YEAR_BASE + timeptr->tm_year);\r
-  return gMD->ASasctime;\r
-}\r
-\r
-/**\r
-**/\r
-char *\r
-ctime(const time_t *timer)\r
-{\r
-  return asctime(localtime(timer));\r
-}\r
-\r
-/*\r
-** gmtsub is to gmtime as localsub is to localtime.\r
-*/\r
-void\r
-gmtsub(\r
-  const time_t * const  timep,\r
-  const long            offset,\r
-  struct tm    * const  tmp\r
-  )\r
-{\r
-#ifdef _REENTRANT\r
-  static mutex_t gmt_mutex = MUTEX_INITIALIZER;\r
-#endif\r
-\r
-  mutex_lock(&gmt_mutex);\r
-  if (!gmt_is_set) {\r
-    gmt_is_set = TRUE;\r
-#ifdef ALL_STATE\r
-    gmtptr = (struct state *) malloc(sizeof *gmtptr);\r
-    if (gmtptr != NULL)\r
-#endif /* defined ALL_STATE */\r
-      gmtload(gmtptr);\r
-  }\r
-  mutex_unlock(&gmt_mutex);\r
-  timesub(timep, offset, gmtptr, tmp);\r
-#ifdef TM_ZONE\r
-  /*\r
-  ** Could get fancy here and deliver something such as\r
-  ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,\r
-  ** but this is no time for a treasure hunt.\r
-  */\r
-  if (offset != 0)\r
-    tmp->TM_ZONE = (__aconst char *)__UNCONST(wildabbr);\r
-  else {\r
-#ifdef ALL_STATE\r
-    if (gmtptr == NULL)\r
-      tmp->TM_ZONE = (__aconst char *)__UNCONST(gmt);\r
-    else  tmp->TM_ZONE = gmtptr->chars;\r
-#endif /* defined ALL_STATE */\r
-#ifndef ALL_STATE\r
-    tmp->TM_ZONE = gmtptr->chars;\r
-#endif /* State Farm */\r
-  }\r
-#endif /* defined TM_ZONE */\r
-}\r
-\r
-/**\r
-**/\r
-struct tm *\r
-gmtime(const time_t *timer)\r
-{\r
-  gmtsub(timer, 0L, &gMD->BDTime);\r
-  return &gMD->BDTime;\r
-}\r
-\r
-static void\r
-localsub(const time_t * const timep, const long   offset, struct tm * const tmp)\r
-{\r
-  register struct state *   sp;\r
-  register const struct ttinfo *  ttisp;\r
-  register int      i;\r
-  const time_t      t = *timep;\r
-\r
-  sp = lclptr;\r
-#ifdef ALL_STATE\r
-  if (sp == NULL) {\r
-    gmtsub(timep, offset, tmp);\r
-    return;\r
-  }\r
-#endif /* defined ALL_STATE */\r
-  if (sp->timecnt == 0 || t < sp->ats[0]) {\r
-    i = 0;\r
-    while (sp->ttis[i].tt_isdst)\r
-      if (++i >= sp->typecnt) {\r
-        i = 0;\r
-        break;\r
-      }\r
-  } else {\r
-    for (i = 1; i < sp->timecnt; ++i)\r
-      if (t < sp->ats[i])\r
-      break;\r
-    i = sp->types[i - 1];\r
-  }\r
-  ttisp = &sp->ttis[i];\r
-  /*\r
-  ** To get (wrong) behavior that's compatible with System V Release 2.0\r
-  ** you'd replace the statement below with\r
-  **  t += ttisp->tt_gmtoff;\r
-  **  timesub(&t, 0L, sp, tmp);\r
-  */\r
-  timesub(&t, ttisp->tt_gmtoff, sp, tmp);\r
-  tmp->tm_isdst = ttisp->tt_isdst;\r
-  tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];\r
-#ifdef TM_ZONE\r
-  tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];\r
-#endif /* defined TM_ZONE */\r
-}\r
-\r
-/**\r
-**/\r
-struct tm *\r
-localtime(const time_t *timer)\r
-{\r
-  tzset();\r
-  localsub(timer, 0L, &gMD->BDTime);\r
-  return &gMD->BDTime;\r
-}\r