diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-07 13:22:53 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-11-11 00:08:15 +0100 |
| commit | 7861a52adf92a083bb2aed4c35f98d8035dce032 (patch) | |
| tree | 28cd3c40e4c878f730f5df3c1d93bdf91af490c3 /src/libc/newlib | |
| parent | 7fc48e9216ff809da5f8055a50b0be17628ef1df (diff) | |
| download | wnix-7861a52adf92a083bb2aed4c35f98d8035dce032.tar.gz | |
Setup project skeleton
Diffstat (limited to 'src/libc/newlib')
| -rw-r--r-- | src/libc/newlib/CMakeLists.txt | 18 | ||||
| -rw-r--r-- | src/libc/newlib/private_include/sys/_tz_structs.h | 30 | ||||
| -rw-r--r-- | src/libc/newlib/src/CMakeLists.txt | 18 | ||||
| -rw-r--r-- | src/libc/newlib/src/stdlib/CMakeLists.txt | 19 | ||||
| -rw-r--r-- | src/libc/newlib/src/stdlib/div.c | 121 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/CMakeLists.txt | 25 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/gettzinfo.c | 15 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/local.h | 38 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/mktime.c | 288 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/month_lengths.c | 14 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/tzcalc_limits.c | 76 | ||||
| -rw-r--r-- | src/libc/newlib/src/time/tzvars.c | 9 |
12 files changed, 671 insertions, 0 deletions
diff --git a/src/libc/newlib/CMakeLists.txt b/src/libc/newlib/CMakeLists.txt new file mode 100644 index 0000000..aedf961 --- /dev/null +++ b/src/libc/newlib/CMakeLists.txt @@ -0,0 +1,18 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +add_subdirectory(src) +target_include_directories(c PRIVATE private_include) diff --git a/src/libc/newlib/private_include/sys/_tz_structs.h b/src/libc/newlib/private_include/sys/_tz_structs.h new file mode 100644 index 0000000..f20aacb --- /dev/null +++ b/src/libc/newlib/private_include/sys/_tz_structs.h @@ -0,0 +1,30 @@ +#ifndef _SYS__TZ_STRUCTS_H_ +#define _SYS__TZ_STRUCTS_H_ + +#include <time.h> + +typedef struct __tzrule_struct +{ + char ch; + int m; /* Month of year if ch=M */ + int n; /* Week of month if ch=M */ + int d; /* Day of week if ch=M, day of year if ch=J or ch=D */ + int s; /* Time of day in seconds */ + time_t change; + long offset; /* Match type of _timezone. */ +} __tzrule_type; + +typedef struct __tzinfo_struct +{ + int __tznorth; + int __tzyear; + __tzrule_type __tzrule[2]; +} __tzinfo_type; + +__tzinfo_type *__gettzinfo (void); + +extern char *_tzname[2]; +extern int _daylight; +extern long _timezone; + +#endif /* _SYS__TZ_STRUCTS_H_ */ diff --git a/src/libc/newlib/src/CMakeLists.txt b/src/libc/newlib/src/CMakeLists.txt new file mode 100644 index 0000000..f2f8ba4 --- /dev/null +++ b/src/libc/newlib/src/CMakeLists.txt @@ -0,0 +1,18 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +add_subdirectory(stdlib) +add_subdirectory(time) diff --git a/src/libc/newlib/src/stdlib/CMakeLists.txt b/src/libc/newlib/src/stdlib/CMakeLists.txt new file mode 100644 index 0000000..ab499b9 --- /dev/null +++ b/src/libc/newlib/src/stdlib/CMakeLists.txt @@ -0,0 +1,19 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +target_sources(c PRIVATE + div.c +) diff --git a/src/libc/newlib/src/stdlib/div.c b/src/libc/newlib/src/stdlib/div.c new file mode 100644 index 0000000..2a19cae --- /dev/null +++ b/src/libc/newlib/src/stdlib/div.c @@ -0,0 +1,121 @@ +/* +FUNCTION +<<div>>---divide two integers + +INDEX + div + +SYNOPSIS + #include <stdlib.h> + div_t div(int <[n]>, int <[d]>); + +DESCRIPTION +Divide +@tex +$n/d$, +@end tex +@ifnottex +<[n]>/<[d]>, +@end ifnottex +returning quotient and remainder as two integers in a structure <<div_t>>. + +RETURNS +The result is represented with the structure + +. typedef struct +. { +. int quot; +. int rem; +. } div_t; + +where the <<quot>> field represents the quotient, and <<rem>> the +remainder. For nonzero <[d]>, if `<<<[r]> = div(<[n]>,<[d]>);>>' then +<[n]> equals `<<<[r]>.rem + <[d]>*<[r]>.quot>>'. + +To divide <<long>> rather than <<int>> values, use the similar +function <<ldiv>>. + +PORTABILITY +<<div>> is ANSI. + +No supporting OS subroutines are required. +*/ + +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> /* div_t */ + +div_t +div (int num, + int denom) +{ + div_t r; + + r.quot = num / denom; + r.rem = num % denom; + /* + * The ANSI standard says that |r.quot| <= |n/d|, where + * n/d is to be computed in infinite precision. In other + * words, we should always truncate the quotient towards + * 0, never -infinity or +infinity. + * + * Machine division and remainer may work either way when + * one or both of n or d is negative. If only one is + * negative and r.quot has been truncated towards -inf, + * r.rem will have the same sign as denom and the opposite + * sign of num; if both are negative and r.quot has been + * truncated towards -inf, r.rem will be positive (will + * have the opposite sign of num). These are considered + * `wrong'. + * + * If both are num and denom are positive, r will always + * be positive. + * + * This all boils down to: + * if num >= 0, but r.rem < 0, we got the wrong answer. + * In that case, to get the right answer, add 1 to r.quot and + * subtract denom from r.rem. + * if num < 0, but r.rem > 0, we also have the wrong answer. + * In this case, to get the right answer, subtract 1 from r.quot and + * add denom to r.rem. + */ + if (num >= 0 && r.rem < 0) { + ++r.quot; + r.rem -= denom; + } + else if (num < 0 && r.rem > 0) { + --r.quot; + r.rem += denom; + } + return (r); +} diff --git a/src/libc/newlib/src/time/CMakeLists.txt b/src/libc/newlib/src/time/CMakeLists.txt new file mode 100644 index 0000000..ea7167f --- /dev/null +++ b/src/libc/newlib/src/time/CMakeLists.txt @@ -0,0 +1,25 @@ +# wnix, a Unix-like operating system for WebAssembly applications. +# Copyright (C) 2025 Xavier Del Campo Romero +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +target_sources(c PRIVATE + gettzinfo.c + month_lengths.c + mktime.c + tzvars.c + tzcalc_limits.c +) + +target_compile_definitions(c PRIVATE __SINGLE_THREAD__) diff --git a/src/libc/newlib/src/time/gettzinfo.c b/src/libc/newlib/src/time/gettzinfo.c new file mode 100644 index 0000000..c28e72f --- /dev/null +++ b/src/libc/newlib/src/time/gettzinfo.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include "local.h" + +/* Shared timezone information for libc/time functions. */ +static __tzinfo_type tzinfo = {1, 0, + { {'J', 0, 0, 0, 0, (time_t)0, 0L }, + {'J', 0, 0, 0, 0, (time_t)0, 0L } + } +}; + +__tzinfo_type * +__gettzinfo (void) +{ + return &tzinfo; +} diff --git a/src/libc/newlib/src/time/local.h b/src/libc/newlib/src/time/local.h new file mode 100644 index 0000000..41940c0 --- /dev/null +++ b/src/libc/newlib/src/time/local.h @@ -0,0 +1,38 @@ +/* local header used by libc/time routines */ +#include <time.h> +#include <sys/_tz_structs.h> + +#define SECSPERMIN 60L +#define MINSPERHOUR 60L +#define HOURSPERDAY 24L +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 + +#define YEAR_BASE 1900 +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY 4 +#define EPOCH_YEARS_SINCE_LEAP 2 +#define EPOCH_YEARS_SINCE_CENTURY 70 +#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370 + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +int __tzcalc_limits (int __year); + +extern const int __month_lengths[2][MONSPERYEAR]; + +void _tzset_unlocked (void); + +/* locks for multi-threading */ +#ifdef __SINGLE_THREAD__ +#define TZ_LOCK +#define TZ_UNLOCK +#else +#define TZ_LOCK __tz_lock() +#define TZ_UNLOCK __tz_unlock() +#endif + +void __tz_lock (void); +void __tz_unlock (void); diff --git a/src/libc/newlib/src/time/mktime.c b/src/libc/newlib/src/time/mktime.c new file mode 100644 index 0000000..4ca1493 --- /dev/null +++ b/src/libc/newlib/src/time/mktime.c @@ -0,0 +1,288 @@ +/* + * mktime.c + * Original Author: G. Haley + * + * Converts the broken-down time, expressed as local time, in the structure + * pointed to by tim_p into a calendar time value. The original values of the + * tm_wday and tm_yday fields of the structure are ignored, and the original + * values of the other fields have no restrictions. On successful completion + * the fields of the structure are set to represent the specified calendar + * time. Returns the specified calendar time. If the calendar time can not be + * represented, returns the value (time_t) -1. + * + * Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland. + */ + +/* +FUNCTION +<<mktime>>---convert time to arithmetic representation + +INDEX + mktime + +SYNOPSIS + #include <time.h> + time_t mktime(struct tm *<[timp]>); + +DESCRIPTION +<<mktime>> assumes the time at <[timp]> is a local time, and converts +its representation from the traditional representation defined by +<<struct tm>> into a representation suitable for arithmetic. + +<<localtime>> is the inverse of <<mktime>>. + +RETURNS +If the contents of the structure at <[timp]> do not form a valid +calendar time representation, the result is <<-1>>. Otherwise, the +result is the time, converted to a <<time_t>> value. + +PORTABILITY +ANSI C requires <<mktime>>. + +<<mktime>> requires no supporting OS subroutines. +*/ + +#include "local.h" +#include <stdlib.h> +#include <sys/_tz_structs.h> +#include <time.h> + +#define TZ_LOCK +#define TZ_UNLOCK +#define _tzset_unlocked() +#define YEAR_BASE 1900 + +#define _SEC_IN_MINUTE 60L +#define _SEC_IN_HOUR 3600L +#define _SEC_IN_DAY 86400L + +static const int DAYS_IN_MONTH[12] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) + +static const int _DAYS_BEFORE_MONTH[12] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) +#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) + +static void +validate_structure (struct tm *tim_p) +{ + div_t res; + int days_in_feb = 28; + + /* calculate time & date to account for out of range values */ + if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) + { + res = div (tim_p->tm_sec, 60); + tim_p->tm_min += res.quot; + if ((tim_p->tm_sec = res.rem) < 0) + { + tim_p->tm_sec += 60; + --tim_p->tm_min; + } + } + + if (tim_p->tm_min < 0 || tim_p->tm_min > 59) + { + res = div (tim_p->tm_min, 60); + tim_p->tm_hour += res.quot; + if ((tim_p->tm_min = res.rem) < 0) + { + tim_p->tm_min += 60; + --tim_p->tm_hour; + } + } + + if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) + { + res = div (tim_p->tm_hour, 24); + tim_p->tm_mday += res.quot; + if ((tim_p->tm_hour = res.rem) < 0) + { + tim_p->tm_hour += 24; + --tim_p->tm_mday; + } + } + + if (tim_p->tm_mon < 0 || tim_p->tm_mon > 11) + { + res = div (tim_p->tm_mon, 12); + tim_p->tm_year += res.quot; + if ((tim_p->tm_mon = res.rem) < 0) + { + tim_p->tm_mon += 12; + --tim_p->tm_year; + } + } + + if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) + days_in_feb = 29; + + if (tim_p->tm_mday <= 0) + { + while (tim_p->tm_mday <= 0) + { + if (--tim_p->tm_mon == -1) + { + tim_p->tm_year--; + tim_p->tm_mon = 11; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); + } + } + else + { + while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) + { + tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); + if (++tim_p->tm_mon == 12) + { + tim_p->tm_year++; + tim_p->tm_mon = 0; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + } + } +} + +time_t +mktime (struct tm *tim_p) +{ + time_t tim = 0; + long days = 0; + int year, isdst=0; + __tzinfo_type *tz = __gettzinfo (); + + /* validate structure */ + validate_structure (tim_p); + + /* compute hours, minutes, seconds */ + tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + + (tim_p->tm_hour * _SEC_IN_HOUR); + + /* compute days in year */ + days += tim_p->tm_mday - 1; + days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; + if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) + days++; + + /* compute day of the year */ + tim_p->tm_yday = days; + + if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000) + return (time_t) -1; + + /* compute days in other years */ + if ((year = tim_p->tm_year) > 70) + { + for (year = 70; year < tim_p->tm_year; year++) + days += _DAYS_IN_YEAR (year); + } + else if (year < 70) + { + for (year = 69; year > tim_p->tm_year; year--) + days -= _DAYS_IN_YEAR (year); + days -= _DAYS_IN_YEAR (year); + } + + /* compute total seconds */ + tim += (time_t)days * _SEC_IN_DAY; + + TZ_LOCK; + + _tzset_unlocked (); + + if (_daylight) + { + int tm_isdst; + int y = tim_p->tm_year + YEAR_BASE; + /* Convert user positive into 1 */ + tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; + isdst = tm_isdst; + + if (y == tz->__tzyear || __tzcalc_limits (y)) + { + /* calculate start of dst in dst local time and + start of std in both std local time and dst local time */ + time_t startdst_dst = tz->__tzrule[0].change + - (time_t) tz->__tzrule[1].offset; + time_t startstd_dst = tz->__tzrule[1].change + - (time_t) tz->__tzrule[1].offset; + time_t startstd_std = tz->__tzrule[1].change + - (time_t) tz->__tzrule[0].offset; + /* if the time is in the overlap between dst and std local times */ + if (tim >= startstd_std && tim < startstd_dst) + ; /* we let user decide or leave as -1 */ + else + { + isdst = (tz->__tznorth + ? (tim >= startdst_dst && tim < startstd_std) + : (tim >= startdst_dst || tim < startstd_std)); + /* if user committed and was wrong, perform correction, but not + * if the user has given a negative value (which + * asks mktime() to determine if DST is in effect or not) */ + if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1) + { + /* we either subtract or add the difference between + time zone offsets, depending on which way the user got it + wrong. The diff is typically one hour, or 3600 seconds, + and should fit in a 16-bit int, even though offset + is a long to accomodate 12 hours. */ + int diff = (int) (tz->__tzrule[0].offset + - tz->__tzrule[1].offset); + if (!isdst) + diff = -diff; + tim_p->tm_sec += diff; + tim += diff; /* we also need to correct our current time calculation */ + int mday = tim_p->tm_mday; + validate_structure (tim_p); + mday = tim_p->tm_mday - mday; + /* roll over occurred */ + if (mday) { + /* compensate for month roll overs */ + if (mday > 1) + mday = -1; + else if (mday < -1) + mday = 1; + /* update days for wday calculation */ + days += mday; + /* handle yday */ + if ((tim_p->tm_yday += mday) < 0) { + --year; + tim_p->tm_yday = _DAYS_IN_YEAR(year) - 1; + } else { + mday = _DAYS_IN_YEAR(year); + if (tim_p->tm_yday > (mday - 1)) + tim_p->tm_yday -= mday; + } + } + } + } + } + } + + /* add appropriate offset to put time in gmt format */ + if (isdst == 1) + tim += (time_t) tz->__tzrule[1].offset; + else /* otherwise assume std time */ + tim += (time_t) tz->__tzrule[0].offset; + + TZ_UNLOCK; + + /* reset isdst flag to what we have calculated */ + tim_p->tm_isdst = isdst; + + /* compute day of the week */ + if ((tim_p->tm_wday = (days + 4) % 7) < 0) + tim_p->tm_wday += 7; + + return tim; +} diff --git a/src/libc/newlib/src/time/month_lengths.c b/src/libc/newlib/src/time/month_lengths.c new file mode 100644 index 0000000..03fac2f --- /dev/null +++ b/src/libc/newlib/src/time/month_lengths.c @@ -0,0 +1,14 @@ +/* + * month_lengths.c + * + * Array __month_lengths[] is (indirectly) needed by tzset(), mktime(), + * gmtime() and localtime(). To break any dependencies, this array is moved to + * separate source file. + */ + +#include "local.h" + +const int __month_lengths[2][MONSPERYEAR] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +} ; diff --git a/src/libc/newlib/src/time/tzcalc_limits.c b/src/libc/newlib/src/time/tzcalc_limits.c new file mode 100644 index 0000000..00044a5 --- /dev/null +++ b/src/libc/newlib/src/time/tzcalc_limits.c @@ -0,0 +1,76 @@ +/* + * tzcalc_limits.c + * Original Author: Adapted from tzcode maintained by Arthur David Olson. + * Modifications: + * - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston + * - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru> + * - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru> + * - Moved __tzcalc_limits() to separate file - 05/09/14, Freddie Chopin <freddie_chopin@op.pl> + */ + +#include "local.h" + +int +__tzcalc_limits (int year) +{ + int days, year_days, years; + int i, j; + __tzinfo_type *const tz = __gettzinfo (); + + if (year < EPOCH_YEAR) + return 0; + + tz->__tzyear = year; + + years = (year - EPOCH_YEAR); + + year_days = years * 365 + + (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - + (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + + (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400; + + for (i = 0; i < 2; ++i) + { + if (tz->__tzrule[i].ch == 'J') + { + /* The Julian day n (1 <= n <= 365). */ + days = year_days + tz->__tzrule[i].d + + (isleap(year) && tz->__tzrule[i].d >= 60); + /* Convert to yday */ + --days; + } + else if (tz->__tzrule[i].ch == 'D') + days = year_days + tz->__tzrule[i].d; + else + { + const int yleap = isleap(year); + int m_day, m_wday, wday_diff; + const int *const ip = __month_lengths[yleap]; + + days = year_days; + + for (j = 1; j < tz->__tzrule[i].m; ++j) + days += ip[j-1]; + + m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK; + + wday_diff = tz->__tzrule[i].d - m_wday; + if (wday_diff < 0) + wday_diff += DAYSPERWEEK; + m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff; + + while (m_day >= ip[j-1]) + m_day -= DAYSPERWEEK; + + days += m_day; + } + + /* store the change-over time in GMT form by adding offset */ + tz->__tzrule[i].change = (time_t) days * SECSPERDAY + + tz->__tzrule[i].s + tz->__tzrule[i].offset; + } + + tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change); + + return 1; +} diff --git a/src/libc/newlib/src/time/tzvars.c b/src/libc/newlib/src/time/tzvars.c new file mode 100644 index 0000000..aabf3c4 --- /dev/null +++ b/src/libc/newlib/src/time/tzvars.c @@ -0,0 +1,9 @@ +#include <time.h> +#include <sys/_tz_structs.h> + +/* Global timezone variables. */ + +/* Default timezone to GMT */ +char *_tzname[2] = {"GMT", "GMT"}; +int _daylight = 0; +long _timezone = 0; |
