summaryrefslogtreecommitdiffstats
path: root/contrib/patch/maketime.c
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2004-04-30 20:33:08 +0000
committermarius <marius@FreeBSD.org>2004-04-30 20:33:08 +0000
commit9fc948cd79a9d70e00c23f1b95ec9da3dc4f7852 (patch)
tree03e30298ca0e732e53f45971a881ba527ebfad7b /contrib/patch/maketime.c
parent54564c74e31dd64140489ef3c4c566d7b7385011 (diff)
downloadFreeBSD-src-9fc948cd79a9d70e00c23f1b95ec9da3dc4f7852.zip
FreeBSD-src-9fc948cd79a9d70e00c23f1b95ec9da3dc4f7852.tar.gz
This commit was generated by cvs2svn to compensate for changes in r128777,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/patch/maketime.c')
-rw-r--r--contrib/patch/maketime.c391
1 files changed, 0 insertions, 391 deletions
diff --git a/contrib/patch/maketime.c b/contrib/patch/maketime.c
deleted file mode 100644
index e66f9df..0000000
--- a/contrib/patch/maketime.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* Convert struct partime into time_t. */
-
-/* Copyright 1992, 1993, 1994, 1995, 1997 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
- This file is part of RCS.
-
- RCS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with RCS; see the file COPYING.
- If not, write to the Free Software Foundation,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
- */
-
-#if has_conf_h
-# include <conf.h>
-#else
-# if HAVE_CONFIG_H
-# include <config.h>
-# else
-# ifndef __STDC__
-# define const
-# endif
-# endif
- /* MIPS RISCOS4.52 defines time_t in <sys/types.h> not <time.h>. */
-# include <sys/types.h>
-# if HAVE_LIMITS_H
-# include <limits.h>
-# endif
-# ifndef LONG_MIN
-# define LONG_MIN (-1-2147483647L)
-# endif
-# if STDC_HEADERS
-# include <stdlib.h>
-# endif
-# include <time.h>
-# ifdef __STDC__
-# define P(x) x
-# else
-# define P(x) ()
-# endif
-#endif
-
-#include <partime.h>
-#include <maketime.h>
-
-char const maketId[] =
- "$Id: maketime.c,v 5.15 1997/06/17 16:54:36 eggert Exp $";
-
-static int isleap P ((int));
-static int month_days P ((struct tm const *));
-static time_t maketime P ((struct partime const *, time_t));
-
-/* For maximum portability, use only localtime and gmtime.
- Make no assumptions about the time_t epoch or the range of time_t values.
- Avoid mktime because it's not universal and because there's no easy,
- portable way for mktime to yield the inverse of gmtime. */
-
-#define TM_YEAR_ORIGIN 1900
-
-static int
-isleap (y)
- int y;
-{
- return (y & 3) == 0 && (y % 100 != 0 || y % 400 == 0);
-}
-
-/* days in year before start of months 0-12 */
-static int const month_yday[] =
-{
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-};
-
-/* Yield the number of days in TM's month. */
-static int
-month_days (tm)
- struct tm const *tm;
-{
- int m = tm->tm_mon;
- return (month_yday[m + 1] - month_yday[m]
- + (m == 1 && isleap (tm->tm_year + TM_YEAR_ORIGIN)));
-}
-
-/* Convert UNIXTIME to struct tm form.
- Use gmtime if available and if !LOCALZONE, localtime otherwise. */
-struct tm *
-time2tm (unixtime, localzone)
- time_t unixtime;
- int localzone;
-{
- struct tm *tm;
-#ifdef TZ_is_unset
- static char const *TZ;
- if (!TZ && !(TZ = getenv ("TZ")))
- TZ_is_unset ("The TZ environment variable is not set; please set it to your timezone");
-#endif
- if (localzone || !(tm = gmtime (&unixtime)))
- tm = localtime (&unixtime);
- return tm;
-}
-
-/* Yield A - B, measured in seconds. */
-time_t
-difftm (a, b)
- struct tm const *a;
- struct tm const *b;
-{
- int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
- int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
- int ac = ay / 100 - (ay % 100 < 0);
- int bc = by / 100 - (by % 100 < 0);
- int difference_in_day_of_year = a->tm_yday - b->tm_yday;
- int intervening_leap_days = (((ay >> 2) - (by >> 2))
- - (ac - bc)
- + ((ac >> 2) - (bc >> 2)));
- time_t difference_in_years = ay - by;
- time_t difference_in_days
- = (difference_in_years * 365
- + (intervening_leap_days + difference_in_day_of_year));
- return (((((difference_in_days * 24
- + (a->tm_hour - b->tm_hour))
- * 60)
- + (a->tm_min - b->tm_min))
- * 60)
- + (a->tm_sec - b->tm_sec));
-}
-
-/*
- * Adjust time T by adding SECONDS. SECONDS must be at most 24 hours' worth.
- * Adjust only T's year, mon, mday, hour, min and sec members;
- * plus adjust wday if it is defined.
- */
-void
-adjzone (t, seconds)
- register struct tm *t;
- long seconds;
-{
- /*
- * This code can be off by a second if SECONDS is not a multiple of 60,
- * if T is local time, and if a leap second happens during this minute.
- * But this bug has never occurred, and most likely will not ever occur.
- * Liberia, the last country for which SECONDS % 60 was nonzero,
- * switched to UTC in May 1972; the first leap second was in June 1972.
- */
- int leap_second = t->tm_sec == 60;
- long sec = seconds + (t->tm_sec - leap_second);
- if (sec < 0)
- {
- if ((t->tm_min -= (59 - sec) / 60) < 0)
- {
- if ((t->tm_hour -= (59 - t->tm_min) / 60) < 0)
- {
- t->tm_hour += 24;
- if (TM_DEFINED (t->tm_wday) && --t->tm_wday < 0)
- t->tm_wday = 6;
- if (--t->tm_mday <= 0)
- {
- if (--t->tm_mon < 0)
- {
- --t->tm_year;
- t->tm_mon = 11;
- }
- t->tm_mday = month_days (t);
- }
- }
- t->tm_min += 24 * 60;
- }
- sec += 24L * 60 * 60;
- }
- else if (60 <= (t->tm_min += sec / 60))
- if (24 <= (t->tm_hour += t->tm_min / 60))
- {
- t->tm_hour -= 24;
- if (TM_DEFINED (t->tm_wday) && ++t->tm_wday == 7)
- t->tm_wday = 0;
- if (month_days (t) < ++t->tm_mday)
- {
- if (11 < ++t->tm_mon)
- {
- ++t->tm_year;
- t->tm_mon = 0;
- }
- t->tm_mday = 1;
- }
- }
- t->tm_min %= 60;
- t->tm_sec = (int) (sec % 60) + leap_second;
-}
-
-/*
- * Convert TM to time_t, using localtime if LOCALZONE and gmtime otherwise.
- * Use only TM's year, mon, mday, hour, min, and sec members.
- * Ignore TM's old tm_yday and tm_wday, but fill in their correct values.
- * Yield -1 on failure (e.g. a member out of range).
- * Posix 1003.1-1990 doesn't allow leap seconds, but some implementations
- * have them anyway, so allow them if localtime/gmtime does.
- */
-time_t
-tm2time (tm, localzone)
- struct tm *tm;
- int localzone;
-{
- /* Cache the most recent t,tm pairs; 1 for gmtime, 1 for localtime. */
- static time_t t_cache[2];
- static struct tm tm_cache[2];
-
- time_t d, gt;
- struct tm const *gtm;
- /*
- * The maximum number of iterations should be enough to handle any
- * combinations of leap seconds, time zone rule changes, and solar time.
- * 4 is probably enough; we use a bigger number just to be safe.
- */
- int remaining_tries = 8;
-
- /* Avoid subscript errors. */
- if (12 <= (unsigned) tm->tm_mon)
- return -1;
-
- tm->tm_yday = month_yday[tm->tm_mon] + tm->tm_mday
- - (tm->tm_mon < 2 || !isleap (tm->tm_year + TM_YEAR_ORIGIN));
-
- /* Make a first guess. */
- gt = t_cache[localzone];
- gtm = gt ? &tm_cache[localzone] : time2tm (gt, localzone);
-
- /* Repeatedly use the error from the guess to improve the guess. */
- while ((d = difftm (tm, gtm)) != 0)
- {
- if (--remaining_tries == 0)
- return -1;
- gt += d;
- gtm = time2tm (gt, localzone);
- }
-
- /*
- * Check that the guess actually matches;
- * overflow can cause difftm to yield 0 even on differing times,
- * or tm may have members out of range (e.g. bad leap seconds).
- */
-#define TM_DIFFER(a,b) \
- ( \
- ((a)->tm_year ^ (b)->tm_year) | \
- ((a)->tm_mon ^ (b)->tm_mon) | \
- ((a)->tm_mday ^ (b)->tm_mday) | \
- ((a)->tm_hour ^ (b)->tm_hour) | \
- ((a)->tm_min ^ (b)->tm_min) | \
- ((a)->tm_sec ^ (b)->tm_sec) \
- )
- if (TM_DIFFER (tm, gtm))
- {
- /*
- * If gt is a leap second, try gt+1; if it is one greater than
- * a leap second, try gt-1; otherwise, it doesn't matter.
- * Leap seconds always fall at month end.
- */
- int yd = tm->tm_year - gtm->tm_year;
- gt += yd + (yd ? 0 : tm->tm_mon - gtm->tm_mon);
- gtm = time2tm (gt, localzone);
- if (TM_DIFFER (tm, gtm))
- return -1;
- }
- t_cache[localzone] = gt;
- tm_cache[localzone] = *gtm;
-
- tm->tm_wday = gtm->tm_wday;
- return gt;
-}
-
-/*
- * Check *PT and convert it to time_t.
- * If it is incompletely specified, use DEFAULT_TIME to fill it out.
- * Use localtime if PT->zone is the special value TM_LOCAL_ZONE.
- * Yield -1 on failure.
- * ISO 8601 day-of-year and week numbers are not yet supported.
- */
-static time_t
-maketime (pt, default_time)
- struct partime const *pt;
- time_t default_time;
-{
- int localzone, wday;
- struct tm tm;
- struct tm *tm0 = 0;
- time_t r;
-
- tm0 = 0; /* Keep gcc -Wall happy. */
- localzone = pt->zone == TM_LOCAL_ZONE;
-
- tm = pt->tm;
-
- if (TM_DEFINED (pt->ymodulus) || !TM_DEFINED (tm.tm_year))
- {
- /* Get tm corresponding to default time. */
- tm0 = time2tm (default_time, localzone);
- if (!localzone)
- adjzone (tm0, pt->zone);
- }
-
- if (TM_DEFINED (pt->ymodulus))
- tm.tm_year +=
- (tm0->tm_year + TM_YEAR_ORIGIN) / pt->ymodulus * pt->ymodulus;
- else if (!TM_DEFINED (tm.tm_year))
- {
- /* Set default year, month, day from current time. */
- tm.tm_year = tm0->tm_year + TM_YEAR_ORIGIN;
- if (!TM_DEFINED (tm.tm_mon))
- {
- tm.tm_mon = tm0->tm_mon;
- if (!TM_DEFINED (tm.tm_mday))
- tm.tm_mday = tm0->tm_mday;
- }
- }
-
- /* Convert from partime year (Gregorian) to Posix year. */
- tm.tm_year -= TM_YEAR_ORIGIN;
-
- /* Set remaining default fields to be their minimum values. */
- if (!TM_DEFINED (tm.tm_mon))
- tm.tm_mon = 0;
- if (!TM_DEFINED (tm.tm_mday))
- tm.tm_mday = 1;
- if (!TM_DEFINED (tm.tm_hour))
- tm.tm_hour = 0;
- if (!TM_DEFINED (tm.tm_min))
- tm.tm_min = 0;
- if (!TM_DEFINED (tm.tm_sec))
- tm.tm_sec = 0;
-
- if (!localzone)
- adjzone (&tm, -pt->zone);
- wday = tm.tm_wday;
-
- /* Convert and fill in the rest of the tm. */
- r = tm2time (&tm, localzone);
-
- /* Check weekday. */
- if (r != -1 && TM_DEFINED (wday) && wday != tm.tm_wday)
- return -1;
-
- return r;
-}
-
-/* Parse a free-format date in SOURCE, yielding a Unix format time. */
-time_t
-str2time (source, default_time, default_zone)
- char const *source;
- time_t default_time;
- long default_zone;
-{
- struct partime pt;
-
- if (*partime (source, &pt))
- return -1;
- if (pt.zone == TM_UNDEFINED_ZONE)
- pt.zone = default_zone;
- return maketime (&pt, default_time);
-}
-
-#if TEST
-#include <stdio.h>
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- time_t default_time = time ((time_t *) 0);
- long default_zone = argv[1] ? atol (argv[1]) : 0;
- char buf[1000];
- while (fgets (buf, sizeof (buf), stdin))
- {
- time_t t = str2time (buf, default_time, default_zone);
- printf ("%s", asctime (gmtime (&t)));
- }
- return 0;
-}
-#endif
OpenPOWER on IntegriCloud