From 341aaf8dc1e57d0b72d81bd51cc79d0d36c4f56b Mon Sep 17 00:00:00 2001 From: eck Date: Mon, 12 Jun 1989 15:22:14 +0000 Subject: [PATCH] Initial revision --- lang/cem/libcc.ansi/time/LIST | 13 +++ lang/cem/libcc.ansi/time/asctime.c | 60 ++++++++++ lang/cem/libcc.ansi/time/clock.c | 19 +++ lang/cem/libcc.ansi/time/ctime.c | 12 ++ lang/cem/libcc.ansi/time/difftime.c | 14 +++ lang/cem/libcc.ansi/time/gmtime.c | 41 +++++++ lang/cem/libcc.ansi/time/loc_incl.h | 20 ++++ lang/cem/libcc.ansi/time/localtime.c | 32 +++++ lang/cem/libcc.ansi/time/misc.c | 142 ++++++++++++++++++++++ lang/cem/libcc.ansi/time/mktime.c | 131 +++++++++++++++++++++ lang/cem/libcc.ansi/time/strftime.c | 168 +++++++++++++++++++++++++++ lang/cem/libcc.ansi/time/time.c | 19 +++ lang/cem/libcc.ansi/time/tzset.c | 16 +++ 13 files changed, 687 insertions(+) create mode 100644 lang/cem/libcc.ansi/time/LIST create mode 100644 lang/cem/libcc.ansi/time/asctime.c create mode 100644 lang/cem/libcc.ansi/time/clock.c create mode 100644 lang/cem/libcc.ansi/time/ctime.c create mode 100644 lang/cem/libcc.ansi/time/difftime.c create mode 100644 lang/cem/libcc.ansi/time/gmtime.c create mode 100644 lang/cem/libcc.ansi/time/loc_incl.h create mode 100644 lang/cem/libcc.ansi/time/localtime.c create mode 100644 lang/cem/libcc.ansi/time/misc.c create mode 100644 lang/cem/libcc.ansi/time/mktime.c create mode 100644 lang/cem/libcc.ansi/time/strftime.c create mode 100644 lang/cem/libcc.ansi/time/time.c create mode 100644 lang/cem/libcc.ansi/time/tzset.c diff --git a/lang/cem/libcc.ansi/time/LIST b/lang/cem/libcc.ansi/time/LIST new file mode 100644 index 000000000..a1c39e54b --- /dev/null +++ b/lang/cem/libcc.ansi/time/LIST @@ -0,0 +1,13 @@ +tlib +loc_incl.h +ctime.c +asctime.c +localtime.c +clock.c +difftime.c +gmtime.c +mktime.c +strftime.c +time.c +tzset.c +misc.c diff --git a/lang/cem/libcc.ansi/time/asctime.c b/lang/cem/libcc.ansi/time/asctime.c new file mode 100644 index 000000000..d0efa2536 --- /dev/null +++ b/lang/cem/libcc.ansi/time/asctime.c @@ -0,0 +1,60 @@ +/* + * asctime - print a date + */ +/* $Header$ */ + +#include +#include +#include +#include "loc_incl.h" + +#define DATE_STR "??? ??? ?? ??:??:?? ????\n" + +static char * +two_digits(register char *pb, int i, int nospace) +{ + *pb = (i / 10) % 10 + '0'; + if (!nospace && *pb == '0') *pb = ' '; + pb++; + *pb++ = (i % 10) + '0'; + return ++pb; +} + +static char * +four_digits(register char *pb, int i) +{ + i %= 10000; + *pb++ = (i / 1000) + '0'; + i %= 1000; + *pb++ = (i / 100) + '0'; + i %= 100; + *pb++ = (i / 10) + '0'; + *pb++ = (i % 10) + '0'; + return ++pb; +} + +char *asctime(const struct tm *timeptr) +{ + static char buf[26]; + register char *pb = buf, *ps; + register int n; + + strcpy(pb, DATE_STR); + ps = _days[timeptr->tm_wday]; + n = ABB_LEN; + while(--n >= 0) *pb++ = *ps++; + pb++; + ps = _months[timeptr->tm_mon]; + n = ABB_LEN; + while(--n >= 0) *pb++ = *ps++; + pb++; + pb = two_digits( + two_digits( + two_digits(two_digits(pb, timeptr->tm_mday, 0) + , timeptr->tm_hour, 1) + , timeptr->tm_min, 1) + , timeptr->tm_sec, 1); + + four_digits(pb, timeptr->tm_year + 1900); + return buf; +} diff --git a/lang/cem/libcc.ansi/time/clock.c b/lang/cem/libcc.ansi/time/clock.c new file mode 100644 index 000000000..06faa7eb0 --- /dev/null +++ b/lang/cem/libcc.ansi/time/clock.c @@ -0,0 +1,19 @@ +/* + * clock - determine the processor time used + */ +/* $Header$ */ + +#include +#include +#include + +clock_t +clock(void) +{ + struct rusage rusage; + + getrusage(RUSAGE_SELF, &rusage); + + return (((unsigned long)rusage.ru_utime.tv_sec * CLK_TCK) + + rusage.ru_utime.tv_usec); +} diff --git a/lang/cem/libcc.ansi/time/ctime.c b/lang/cem/libcc.ansi/time/ctime.c new file mode 100644 index 000000000..9f01f50ce --- /dev/null +++ b/lang/cem/libcc.ansi/time/ctime.c @@ -0,0 +1,12 @@ +/* + * ctime - convers the calendar time to a string + */ +/* $Header$ */ + +#include + +char * +ctime(const time_t *timer) +{ + return asctime(localtime(timer)); +} diff --git a/lang/cem/libcc.ansi/time/difftime.c b/lang/cem/libcc.ansi/time/difftime.c new file mode 100644 index 000000000..c0de01481 --- /dev/null +++ b/lang/cem/libcc.ansi/time/difftime.c @@ -0,0 +1,14 @@ +/* + * difftime - compute the difference bnetween two calendar times + */ +/* $Header$ */ + +#include + +double +difftime(time_t time1, time_t time0) +{ + if (time0 > time1) + return - (double) (time0 - time1); + else return (double) (time1 - time0); +} diff --git a/lang/cem/libcc.ansi/time/gmtime.c b/lang/cem/libcc.ansi/time/gmtime.c new file mode 100644 index 000000000..07285d0ca --- /dev/null +++ b/lang/cem/libcc.ansi/time/gmtime.c @@ -0,0 +1,41 @@ +/* + * gmtime - convert the calendar time into broken down time + */ +/* $Header$ */ + +#include +#include +#include "loc_incl.h" + +struct tm * +gmtime(register const time_t *timer) +{ + static struct tm br_time; + register struct tm *timep = &br_time; + time_t time = *timer; + register unsigned long dayclock, dayno; + int year = 1970; + + dayclock = time % SECS_DAY; + dayno = time / SECS_DAY; + + timep->tm_sec = dayclock % 60; + timep->tm_min = (dayclock % 3600) / 60; + timep->tm_hour = dayclock / 3600; + timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ + while (dayno >= YEARSIZE(year)) { + dayno -= YEARSIZE(year); + year++; + } + timep->tm_year = year - YEAR1; + timep->tm_yday = dayno; + timep->tm_mon = 0; + while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) { + dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon]; + timep->tm_mon++; + } + timep->tm_mday = dayno + 1; + timep->tm_isdst = 0; + + return timep; +} diff --git a/lang/cem/libcc.ansi/time/loc_incl.h b/lang/cem/libcc.ansi/time/loc_incl.h new file mode 100644 index 000000000..3e72c545e --- /dev/null +++ b/lang/cem/libcc.ansi/time/loc_incl.h @@ -0,0 +1,20 @@ +/* + * loc_incl.h - some local definitions + */ +/* $Header$ */ + +#define YEAR1 1900 /* the first year */ +#define SECS_DAY (24L * 60L * 60L) +#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) +#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) +#define FIRSTSUNDAY(year) (((year)->tm_yday - (year)->tm_wday + 420) % 7) +#define TIME_MAX ULONG_MAX +#define ABB_LEN 3 + +extern const int _ytab[2][12]; +extern const char *_days[]; +extern const char *_months[]; +extern char *__tzname[]; + +long int _tzone(void); +unsigned _dstget(struct tm *timep); diff --git a/lang/cem/libcc.ansi/time/localtime.c b/lang/cem/libcc.ansi/time/localtime.c new file mode 100644 index 000000000..df90fd9d6 --- /dev/null +++ b/lang/cem/libcc.ansi/time/localtime.c @@ -0,0 +1,32 @@ +/* + * localtime - convert a calendar time into broken down time + */ +/* $Header$ */ + +#include +#include "loc_incl.h" + +/* We must be careful, since an int can't represent all the seconds in a day. + * Hence the adjustment of minutes when adding timezone and dst information. + * This assumes that both must be expressable in multiples of a minute. + * Furthermore, it is assumed that both fit into an integer when expressed as + * minutes (this is about 22 days, so this should not cause any problems). + */ +struct tm * +localtime(const time_t *timer) +{ + struct tm *timep; + long tz = _tzone(); + unsigned dst; + + timep = gmtime(timer); /* tm->tm_isdst == 0 */ + timep->tm_min -= tz / 60; + mktime(timep); + + dst = _dstget(timep); + if (dst) { + timep->tm_min += dst / 60; + mktime(timep); + } + return timep; +} diff --git a/lang/cem/libcc.ansi/time/misc.c b/lang/cem/libcc.ansi/time/misc.c new file mode 100644 index 000000000..557a12b4e --- /dev/null +++ b/lang/cem/libcc.ansi/time/misc.c @@ -0,0 +1,142 @@ +/* + * misc - data and miscellaneous routines + */ +/* $Header$ */ + +#include +#include +#include + +#ifdef __BSD4_2 +#include +#elif !defined(__USG) +struct timeb +{ + timez_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; +#endif + +#include "loc_incl.h" + +#ifdef __USG +long timezone = -1 * 60; +int daylight = 1; +char *tzname[] = {"MET", "MDT",}; +#endif + +long __timezone = -1 * 60; +static int __daylight = 1; +char *__tzname[] = {"MET", "MDT",}; + +const char *_days[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; + +const char *_months[] = { + "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December" + }; + +const int _ytab[2][12] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + +int +_leap(int year) +{ + return (!(year % 4) && ((year % 100) || !(year % 400))); +} + +long +_tzone(void) +{ + register char *p = getenv("TZ"); + register int n = 0; + int sign = 1; + +#ifdef __BSD4_2 + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + __daylight = tz.tz_dsttime; + __timezone = tz.tz_minuteswest * 60; + +#elif !defined(__USG) + struct timeb time; + + ftime(&time); + __timezone = time.timezone * 60L; + __daylight = time.dstflag; +#endif + if (p && *p) { + strncpy(__tzname[0], p, 3); + p += 3; + if (*p == '-') { + sign = -1; + p++; + } + + while (*p >= '0' && *p <= '9') + n = 10 * n + (*p++ - '0'); + n *= sign; + __timezone = ((long)(n * 60)) * 60; + __daylight = (*p != '\0'); + strncpy(__tzname[1], p, 3); + } +#ifdef __USG + timezone = __timezone; + daylight = __daylight; + tzname[0] = __tzname[0]; + tzname[1] = __tzname[1]; +#endif + return __timezone; +} + +static int +last_sunday(register int day, register struct tm *timep) +{ + int first = FIRSTSUNDAY(timep); + + if (day >= 58 && LEAPYEAR(1900 + timep->tm_year)) day++; + if (day < first) return first; + return day - (day - first) % 7; +} + +unsigned +_dstget(struct tm *timep) +{ + int begindst, enddst; + + if(__daylight == -1) + _tzone(); + + timep->tm_isdst = __daylight; + if (!__daylight) return 0; + begindst = last_sunday(89, timep); /* last Sun before Apr */ + enddst = last_sunday(272, timep); /* last Sun in Sep */ + + /* The rules for daylight saving time differ for different coutries. + * Implemented here are heuristics that got it right in Holland for + * the last couple of years. There is, of course, no universal + * algorithm. Only tables would work perfect. + */ + if ( (timep->tm_yday>begindst + || (timep->tm_yday == begindst && timep->tm_hour >= 2)) + && (timep->tm_ydaytm_yday == enddst && timep->tm_hour < 3))) { + /* it all happens between 2 and 3 */ + + return 60*60; + } + timep->tm_isdst = 0; + + return 0; +} diff --git a/lang/cem/libcc.ansi/time/mktime.c b/lang/cem/libcc.ansi/time/mktime.c new file mode 100644 index 000000000..ff83e0cea --- /dev/null +++ b/lang/cem/libcc.ansi/time/mktime.c @@ -0,0 +1,131 @@ +/* + * mktime - convert local time into calendar time + */ +/* $Header$ */ + +#include +#include +#include "loc_incl.h" + +time_t +mktime(register struct tm *timep) +{ + int day, year, month, yday; + long tmp_sec, tz = _tzone(); + register time_t seconds, localseconds; + int overflow = 0; + unsigned dst; + + + timep->tm_min += timep->tm_sec / 60; + timep->tm_sec %= 60; + if (timep->tm_sec < 0) { + timep->tm_sec += 60; + timep->tm_min--; + } + timep->tm_hour += timep->tm_min / 60; + timep->tm_min = timep->tm_min % 60; + if (timep->tm_min < 0) { + timep->tm_min += 60; + timep->tm_hour--; + } + day = timep->tm_hour / 24; + timep->tm_hour= timep->tm_hour % 24; + if (timep->tm_hour < 0) { + timep->tm_hour += 24; + day--; + } + timep->tm_year += timep->tm_mon / 12; + timep->tm_mon %= 12; + if (timep->tm_mon < 0) { + timep->tm_mon += 12; + timep->tm_year--; + } + day += (timep->tm_mday - 1); + while (day < 0) { + day += YEARSIZE(YEAR1 + timep->tm_year - 1); + timep->tm_year--; + } + while (day >= YEARSIZE(YEAR1 + timep->tm_year)) { + day -= YEARSIZE(YEAR1 + timep->tm_year); + timep->tm_year++; + } + while (day >= _ytab[LEAPYEAR(YEAR1 + timep->tm_year)][timep->tm_mon]) { + day -= _ytab[LEAPYEAR(YEAR1 + timep->tm_year)][timep->tm_mon]; + if (++(timep->tm_mon) == 12) { + timep->tm_mon = 0; + timep->tm_year++; + } + } + timep->tm_mday = day + 1; + year = 70; + if (timep->tm_year < year) return -1; + seconds = 0; + while (!overflow && year < timep->tm_year) { + tmp_sec = SECS_DAY * YEARSIZE(YEAR1 + year); + if (TIME_MAX - tmp_sec <= seconds) overflow++; + else { + seconds += tmp_sec; + year++; + } + } + yday = month = 0; + while (!overflow && month < timep->tm_mon) { + yday += _ytab[LEAPYEAR(YEAR1 + year)][month]; + month++; + } + yday += (timep->tm_mday - 1); + if (!overflow) { + tmp_sec = yday * SECS_DAY; + if (TIME_MAX - tmp_sec <= seconds) overflow++; + else seconds += tmp_sec; + } + + timep->tm_yday = yday; /* ??? assignments should be later */ + /* day 0 was thursday (4) */ + timep->tm_wday = (seconds / SECS_DAY + 4) % 7; + + if (timep->tm_isdst < 0) + dst = _dstget(timep); + else if (timep->tm_isdst) + dst = 60 * 60; + else dst = 0; + + if (!overflow) { + tmp_sec = timep->tm_hour * 60 * 60; + if (TIME_MAX - tmp_sec <= seconds) overflow++; + else seconds += tmp_sec; + } + + if (!overflow) { + tmp_sec = timep->tm_min * 60; + if (TIME_MAX - tmp_sec <= seconds) overflow++; + else seconds += tmp_sec; + } + + if (!overflow) { + tmp_sec = timep->tm_sec; + if (TIME_MAX - tmp_sec <= seconds) overflow++; + else seconds += tmp_sec; + } + + localseconds = seconds; + + if (!overflow) { + tmp_sec = tz; + if (((tmp_sec > 0) && (TIME_MAX - tmp_sec <= seconds)) + || ((tmp_sec < 0) && (seconds < -tmp_sec))) + overflow++; + else seconds += tmp_sec; + } + + if (!overflow) { + tmp_sec = dst; + if (tmp_sec > seconds) overflow++; + else seconds -= tmp_sec; + } + + if (overflow) return (time_t)-1; + + return seconds; +} diff --git a/lang/cem/libcc.ansi/time/strftime.c b/lang/cem/libcc.ansi/time/strftime.c new file mode 100644 index 000000000..9827c6a1d --- /dev/null +++ b/lang/cem/libcc.ansi/time/strftime.c @@ -0,0 +1,168 @@ +/* + * strftime - convert a structure to a string, controlled by an argument + */ +/* $Header$ */ + +#include +#include "loc_incl.h" + +/* The width can be negative in both s_prnt() as in u_prnt(). This + * indicates that as many characters as needed should be printed. + */ +static char * +s_prnt(char *s, size_t maxsize, const char *str, int width) +{ + while (width > 0 || (width < 0 && *str)) { + if (!maxsize) break; + *s++ = *str++; + maxsize--; + width--; + } + return s; +} + +static char * +u_prnt(char *s, size_t maxsize, unsigned val, int width) +{ + int c; + + c = val % 10; + val = val / 10; + if (--width > 0 || (width < 0 && val != 0)) + s = u_prnt(s, (maxsize ? maxsize - 1 : 0), val, width); + if (maxsize) *s++ = c + '0'; + return s; +} + +size_t +strftime(char *s, size_t maxsize, + const char *format, const struct tm *timeptr) +{ + size_t n; + char *firsts, *olds; + + if (!format) return 0; + + firsts = s; + while (maxsize && *format) { + if (maxsize && *format && *format != '%') { + *s++ = *format++; + maxsize--; + continue; + } + if (*format++ != '%') break; /* maxsize == 0 || !*format */ + + olds = s; + switch (*format++) { + case 'a': + s = s_prnt(s, maxsize, + _days[timeptr->tm_wday], ABB_LEN); + maxsize -= s - olds; + break; + case 'A': + s = s_prnt(s, maxsize, _days[timeptr->tm_wday], -1); + maxsize -= s - olds; + break; + case 'b': + s = s_prnt(s, maxsize, + _months[timeptr->tm_mon], ABB_LEN); + maxsize -= s - olds; + break; + case 'B': + s = s_prnt(s, maxsize, _months[timeptr->tm_mon], -1); + maxsize -= s - olds; + break; + case 'c': + n = strftime(s, maxsize, + "%a %b %d %H:%M:%S %Y", timeptr); + maxsize -= n; + s += n; + break; + case 'd': + s = u_prnt(s, maxsize, timeptr->tm_mday, 2); + maxsize -= s - olds; + break; + case 'H': + s = u_prnt(s, maxsize, timeptr->tm_hour, 2); + maxsize -= s - olds; + break; + case 'I': + s = u_prnt(s, maxsize, + (timeptr->tm_hour + 11) % 12 + 1, 2); + maxsize -= s - olds; + break; + case 'j': + s = u_prnt(s, maxsize, timeptr->tm_yday + 1, 3); + maxsize -= s - olds; + break; + case 'm': + s = u_prnt(s, maxsize, timeptr->tm_mon + 1, 2); + maxsize -= s - olds; + break; + case 'M': + s = u_prnt(s, maxsize, timeptr->tm_min, 2); + maxsize -= s - olds; + break; + case 'p': + s = s_prnt(s, maxsize, + (timeptr->tm_hour < 12) ? "AM" : "PM", 2); + maxsize -= s - olds; + break; + case 'S': + s = u_prnt(s, maxsize, timeptr->tm_sec, 2); + maxsize -= s - olds; + break; + case 'U': + s = u_prnt(s, maxsize, /* ??? */ + (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7, 2); + maxsize -= s - olds; + break; + case 'w': + s = u_prnt(s, maxsize, timeptr->tm_wday, 1); + maxsize -= s - olds; + break; + case 'W': + s = u_prnt(s, maxsize, /* ??? */ + (timeptr->tm_yday+7-(timeptr->tm_wday+6)%7)/7,2); + maxsize -= s - olds; + break; + case 'x': + n = strftime(s, maxsize, "%a %b %d %Y", timeptr); + maxsize -= n; + s += n; + break; + case 'X': + n = strftime(s, maxsize, "%H:%M:%S", timeptr); + maxsize -= n; + s += n; + break; + case 'y': + s = u_prnt(s, maxsize, timeptr->tm_year % 100, 2); + maxsize -= s - olds; + break; + case 'Y': + s = u_prnt(s, maxsize, timeptr->tm_year + 1900, -1); + maxsize -= s - olds; + break; + case 'Z': + s = s_prnt(s, maxsize, + __tzname[(timeptr->tm_isdst > 0)], -1); + maxsize -= s - olds; + break; + case '%': + *s++ = '%'; + maxsize--; + break; + default: + /* A conversion error. Leave the loop. */ + while (*format) format++; + break; + } + + } + if (maxsize) { + *s = '\0'; + return s - firsts; + } + return 0; /* The buffer is full */ +} diff --git a/lang/cem/libcc.ansi/time/time.c b/lang/cem/libcc.ansi/time/time.c new file mode 100644 index 000000000..4b8527889 --- /dev/null +++ b/lang/cem/libcc.ansi/time/time.c @@ -0,0 +1,19 @@ +/* + * time - return the current calendar time (seconds since jan 1, 1970) + */ +/* $Header$ */ + +#include +#include + +time_t +time(time_t *timer) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + if (timer) *timer = tv.tv_sec; + return tv.tv_sec; +} diff --git a/lang/cem/libcc.ansi/time/tzset.c b/lang/cem/libcc.ansi/time/tzset.c new file mode 100644 index 000000000..e1ae1f369 --- /dev/null +++ b/lang/cem/libcc.ansi/time/tzset.c @@ -0,0 +1,16 @@ +/* + * tzset - system V compatibility + */ +/* $Header$ */ + +#ifdef __USG + +#include +#include "loc_incl.h" + +void +tzset(void) +{ + _tzone(); /* does the job */ +} +#endif /* __USG */ -- 2.34.1