Merge branch 'master' of https://gitlab.redox-os.org/redox-os/relibc
This commit is contained in:
@@ -353,14 +353,16 @@ pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int {
|
||||
result as i32
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn mbstowcs(pwcs: *mut wchar_t, s: *const c_char, n: size_t) -> size_t {
|
||||
unimplemented!();
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mbstowcs(pwcs: *mut wchar_t, mut s: *const c_char, n: size_t) -> size_t {
|
||||
let mut state: mbstate_t = mbstate_t {};
|
||||
mbsrtowcs(pwcs, &mut s, n, &mut state)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t) -> c_int {
|
||||
let mut state: mbstate_t = mbstate_t {};
|
||||
mbrtowc(pwc, s, n, &mut state) as c_int
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+123
-61
@@ -198,70 +198,132 @@ pub unsafe extern "C" fn localtime(clock: *const time_t) -> *mut tm {
|
||||
localtime_r(clock, &mut TM)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn localtime_r(clock: *const time_t, r: *mut tm) -> *mut tm {
|
||||
fn leap_year(year: c_int) -> bool {
|
||||
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
||||
}
|
||||
let mut clock = *clock;
|
||||
const MONTH_DAYS: [[c_int; 12]; 2] = [
|
||||
// Non-leap years:
|
||||
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
// Leap years:
|
||||
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
];
|
||||
|
||||
if clock < 0 {
|
||||
unimplemented!("localtime_r with a negative time is to be implemented");
|
||||
}
|
||||
|
||||
let mut days = (clock / (60 * 60 * 24)) as c_int;
|
||||
|
||||
// Epoch, Jan 1 1970, was on a thursday.
|
||||
// Jan 5th was a monday.
|
||||
(*r).tm_wday = (days + 4) % 7;
|
||||
|
||||
(*r).tm_year = 1970;
|
||||
|
||||
loop {
|
||||
let days_in_year = if leap_year((*r).tm_year) { 366 } else { 365 };
|
||||
|
||||
if days < days_in_year {
|
||||
break;
|
||||
}
|
||||
|
||||
days -= days_in_year;
|
||||
(*r).tm_year += 1;
|
||||
}
|
||||
|
||||
(*r).tm_yday = days;
|
||||
|
||||
(*r).tm_sec = (clock % 60) as c_int;
|
||||
(*r).tm_min = ((clock % (60 * 60)) / 60) as c_int;
|
||||
(*r).tm_hour = (clock / (60 * 60)) as c_int;
|
||||
|
||||
const MONTH_DAYS: [[c_int; 12]; 2] = [
|
||||
// Non-leap years:
|
||||
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
// Leap years:
|
||||
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
];
|
||||
|
||||
let leap = if leap_year((*r).tm_year) { 1 } else { 0 };
|
||||
|
||||
loop {
|
||||
let days_in_month = MONTH_DAYS[leap][(*r).tm_mon as usize];
|
||||
|
||||
if days < (*r).tm_mon {
|
||||
break;
|
||||
}
|
||||
|
||||
days -= days_in_month;
|
||||
(*r).tm_mon += 1;
|
||||
}
|
||||
(*r).tm_mday = days as c_int;
|
||||
(*r).tm_isdst = 0;
|
||||
|
||||
r
|
||||
fn leap_year(year: c_int) -> bool {
|
||||
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn mktime(timeptr: *mut tm) -> time_t {
|
||||
unimplemented!();
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut tm {
|
||||
let clock = *clock;
|
||||
|
||||
let mut day = (clock / (60 * 60 * 24)) as c_int;
|
||||
if clock < 0 && clock % (60 * 60 * 24) != 0 {
|
||||
// -1 because for negative values round upwards
|
||||
// -0.3 == 0, but we want -1
|
||||
day -= 1;
|
||||
}
|
||||
|
||||
(*t).tm_sec = (clock % 60) as c_int;
|
||||
(*t).tm_min = ((clock / 60) % 60) as c_int;
|
||||
(*t).tm_hour = ((clock / (60 * 60)) % 24) as c_int;
|
||||
|
||||
while (*t).tm_sec < 0 {
|
||||
(*t).tm_sec += 60;
|
||||
(*t).tm_min -= 1;
|
||||
}
|
||||
while (*t).tm_min < 0 {
|
||||
(*t).tm_min += 60;
|
||||
(*t).tm_hour -= 1;
|
||||
}
|
||||
while (*t).tm_hour < 0 {
|
||||
(*t).tm_hour += 24;
|
||||
}
|
||||
|
||||
// Jan 1th was a thursday, 4th of a zero-indexed week.
|
||||
(*t).tm_wday = (day + 4) % 7;
|
||||
if (*t).tm_wday < 0 {
|
||||
(*t).tm_wday += 7;
|
||||
}
|
||||
|
||||
let mut year = 1970;
|
||||
if day < 0 {
|
||||
while day < 0 {
|
||||
let days_in_year = if leap_year(year) { 366 } else { 365 };
|
||||
|
||||
day += days_in_year;
|
||||
year -= 1;
|
||||
}
|
||||
(*t).tm_year = year - 1900;
|
||||
(*t).tm_yday = day + 1;
|
||||
} else {
|
||||
loop {
|
||||
let days_in_year = if leap_year(year) { 366 } else { 365 };
|
||||
|
||||
if day < days_in_year {
|
||||
break;
|
||||
}
|
||||
|
||||
day -= days_in_year;
|
||||
year += 1;
|
||||
}
|
||||
(*t).tm_year = year - 1900;
|
||||
(*t).tm_yday = day;
|
||||
}
|
||||
|
||||
let leap = if leap_year(year) { 1 } else { 0 };
|
||||
(*t).tm_mon = 0;
|
||||
loop {
|
||||
let days_in_month = MONTH_DAYS[leap][(*t).tm_mon as usize];
|
||||
|
||||
if day < days_in_month {
|
||||
break;
|
||||
}
|
||||
|
||||
day -= days_in_month;
|
||||
(*t).tm_mon += 1;
|
||||
}
|
||||
(*t).tm_mday = 1 + day as c_int;
|
||||
(*t).tm_isdst = 0;
|
||||
|
||||
t
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mktime(t: *mut tm) -> time_t {
|
||||
let mut year = (*t).tm_year + 1900;
|
||||
let mut month = (*t).tm_mon;
|
||||
let mut day = (*t).tm_mday as i64 - 1;
|
||||
|
||||
let leap = if leap_year(year) { 1 } else { 0 };
|
||||
|
||||
if year < 1970 {
|
||||
day = MONTH_DAYS[if leap_year(year) { 1 } else { 0 }][(*t).tm_mon as usize] as i64 - day;
|
||||
|
||||
while year < 1969 {
|
||||
year += 1;
|
||||
day += if leap_year(year) { 366 } else { 365 };
|
||||
}
|
||||
|
||||
while month < 11 {
|
||||
month += 1;
|
||||
day += MONTH_DAYS[leap][month as usize] as i64;
|
||||
}
|
||||
|
||||
-(day * (60 * 60 * 24)
|
||||
- (((*t).tm_hour as i64) * (60 * 60) + ((*t).tm_min as i64) * 60 + (*t).tm_sec as i64))
|
||||
} else {
|
||||
while year > 1970 {
|
||||
year -= 1;
|
||||
day += if leap_year(year) { 366 } else { 365 };
|
||||
}
|
||||
|
||||
while month > 0 {
|
||||
month -= 1;
|
||||
day += MONTH_DAYS[leap][month as usize] as i64;
|
||||
}
|
||||
|
||||
(day * (60 * 60 * 24)
|
||||
+ ((*t).tm_hour as i64) * (60 * 60)
|
||||
+ ((*t).tm_min as i64) * 60
|
||||
+ (*t).tm_sec as i64)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+28
-29
@@ -10,7 +10,6 @@ extern crate time;
|
||||
extern crate va_list as vl;
|
||||
|
||||
use core::ptr;
|
||||
use core::usize;
|
||||
use platform::types::*;
|
||||
use stdio::*;
|
||||
use time::*;
|
||||
@@ -95,7 +94,7 @@ pub unsafe extern "C" fn mbsinit(ps: *const mbstate_t) -> c_int {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mbrlen(s: *const c_char, n: usize, ps: *mut mbstate_t) -> usize {
|
||||
pub unsafe extern "C" fn mbrlen(s: *const c_char, n: size_t, ps: *mut mbstate_t) -> size_t {
|
||||
static mut INTERNAL: mbstate_t = mbstate_t;
|
||||
mbrtowc(ptr::null_mut(), s, n, &mut INTERNAL)
|
||||
}
|
||||
@@ -105,9 +104,9 @@ pub unsafe extern "C" fn mbrlen(s: *const c_char, n: usize, ps: *mut mbstate_t)
|
||||
pub unsafe extern "C" fn mbrtowc(
|
||||
pwc: *mut wchar_t,
|
||||
s: *const c_char,
|
||||
n: usize,
|
||||
n: size_t,
|
||||
ps: *mut mbstate_t,
|
||||
) -> usize {
|
||||
) -> size_t {
|
||||
static mut INTERNAL: mbstate_t = mbstate_t;
|
||||
|
||||
if ps.is_null() {
|
||||
@@ -127,10 +126,10 @@ pub unsafe extern "C" fn mbrtowc(
|
||||
pub unsafe extern "C" fn mbsnrtowcs(
|
||||
dst_ptr: *mut wchar_t,
|
||||
src_ptr: *mut *const c_char,
|
||||
src_len: usize,
|
||||
dst_len: usize,
|
||||
src_len: size_t,
|
||||
dst_len: size_t,
|
||||
ps: *mut mbstate_t,
|
||||
) -> usize {
|
||||
) -> size_t {
|
||||
static mut INTERNAL: mbstate_t = mbstate_t;
|
||||
|
||||
if ps.is_null() {
|
||||
@@ -191,10 +190,10 @@ pub unsafe extern "C" fn mbsnrtowcs(
|
||||
pub extern "C" fn mbsrtowcs(
|
||||
dst: *mut wchar_t,
|
||||
src: *mut *const c_char,
|
||||
len: usize,
|
||||
len: size_t,
|
||||
ps: *mut mbstate_t,
|
||||
) -> usize {
|
||||
unsafe { mbsnrtowcs(dst, src, usize::max_value(), len, ps) }
|
||||
) -> size_t {
|
||||
unsafe { mbsnrtowcs(dst, src, size_t::max_value(), len, ps) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -210,7 +209,7 @@ pub unsafe extern "C" fn putwchar(wc: wchar_t) -> wint_t {
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn swprintf(
|
||||
s: *mut wchar_t,
|
||||
n: usize,
|
||||
n: size_t,
|
||||
format: *const wchar_t,
|
||||
mut ap: va_list,
|
||||
) -> c_int {
|
||||
@@ -250,7 +249,7 @@ pub extern "C" fn vwprintf(format: *const wchar_t, arg: va_list) -> c_int {
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn vswprintf(
|
||||
s: *mut wchar_t,
|
||||
n: usize,
|
||||
n: size_t,
|
||||
format: *const wchar_t,
|
||||
arg: va_list,
|
||||
) -> c_int {
|
||||
@@ -259,7 +258,7 @@ pub extern "C" fn vswprintf(
|
||||
|
||||
//widechar to multibyte
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize {
|
||||
pub extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> size_t {
|
||||
let mut buffer: [c_char; MB_CUR_MAX as usize] = [0; MB_CUR_MAX as usize];
|
||||
let mut wc_cpy = wc;
|
||||
let mut s_cpy = s;
|
||||
@@ -298,17 +297,17 @@ pub extern "C" fn wcscpy(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcscspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
|
||||
pub extern "C" fn wcscspn(ws1: *const wchar_t, ws2: *const wchar_t) -> size_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsftime(
|
||||
wcs: *mut wchar_t,
|
||||
maxsize: usize,
|
||||
maxsize: size_t,
|
||||
format: *const wchar_t,
|
||||
timptr: *mut tm,
|
||||
) -> usize {
|
||||
) -> size_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -318,17 +317,17 @@ pub extern "C" fn wcslen(ws: *const wchar_t) -> c_ulong {
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsncat(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
|
||||
pub extern "C" fn wcsncat(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> *mut wchar_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsncmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize) -> c_int {
|
||||
pub extern "C" fn wcsncmp(ws1: *const wchar_t, ws2: *const wchar_t, n: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsncpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
|
||||
pub extern "C" fn wcsncpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> *mut wchar_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -346,14 +345,14 @@ pub extern "C" fn wcsrchr(ws1: *const wchar_t, ws2: wchar_t) -> *mut wchar_t {
|
||||
pub extern "C" fn wcsrtombs(
|
||||
dst: *mut c_char,
|
||||
src: *mut *const wchar_t,
|
||||
len: usize,
|
||||
len: size_t,
|
||||
ps: *mut mbstate_t,
|
||||
) -> usize {
|
||||
) -> size_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
|
||||
pub extern "C" fn wcsspn(ws1: *const wchar_t, ws2: *const wchar_t) -> size_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -392,12 +391,12 @@ pub extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcswidth(pwcs: *const wchar_t, n: usize) -> c_int {
|
||||
pub extern "C" fn wcswidth(pwcs: *const wchar_t, n: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> usize {
|
||||
pub extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> size_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -412,27 +411,27 @@ pub extern "C" fn wcwidth(wc: wchar_t) -> c_int {
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: usize) -> *mut c_int {
|
||||
pub extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: size_t) -> *mut c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wmemcmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize) -> c_int {
|
||||
pub extern "C" fn wmemcmp(ws1: *const wchar_t, ws2: *const wchar_t, n: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wmemcpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
|
||||
pub extern "C" fn wmemcpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> *mut wchar_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wmemmove(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
|
||||
pub extern "C" fn wmemmove(ws1: *mut wchar_t, ws2: *const wchar_t, n: size_t) -> *mut wchar_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn wmemset(ws1: *mut wchar_t, ws2: wchar_t, n: usize) -> *mut wchar_t {
|
||||
pub extern "C" fn wmemset(ws1: *mut wchar_t, ws2: wchar_t, n: size_t) -> *mut wchar_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ fsync
|
||||
ftruncate
|
||||
getc_unget
|
||||
locale
|
||||
localtime
|
||||
math
|
||||
mem
|
||||
mktime
|
||||
pipe
|
||||
printf
|
||||
rename
|
||||
|
||||
@@ -16,8 +16,10 @@ EXPECT_BINS=\
|
||||
ftruncate \
|
||||
getc_unget \
|
||||
locale \
|
||||
localtime \
|
||||
math \
|
||||
mem \
|
||||
mktime \
|
||||
pipe \
|
||||
printf \
|
||||
rename \
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Year 69, Day of year: 333, Month 10, Day of month: 29, Day of week: 6, 0:0:0
|
||||
Year 69, Day of year: 365, Month 11, Day of month: 31, Day of week: 3, 0:0:0
|
||||
Year 69, Day of year: 365, Month 11, Day of month: 31, Day of week: 3, 23:51:40
|
||||
Year 70, Day of year: 0, Month 0, Day of month: 1, Day of week: 4, 0:0:0
|
||||
Year 118, Day of year: 193, Month 6, Day of month: 13, Day of week: 5, 4:9:10
|
||||
Fri Jul 13 06:03:43 2018
|
||||
@@ -0,0 +1,6 @@
|
||||
31536000
|
||||
-2851200 = -2851200
|
||||
-86400 = -86400
|
||||
-500 = -500
|
||||
0 = 0
|
||||
1531454950 = 1531454950
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
int main() {
|
||||
int day = 60 * 60 * 24;
|
||||
time_t inputs[] = { -(day * 33), -day, -500, 0, 1531454950 };
|
||||
for (int i = 0; i < 5; i += 1) {
|
||||
struct tm* t = localtime(&inputs[i]);
|
||||
|
||||
printf(
|
||||
"Year %d, Day of year: %d, Month %d, Day of month: %d, Day of week: %d, %d:%d:%d\n",
|
||||
t->tm_year, t->tm_yday, t->tm_mon, t->tm_mday, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec
|
||||
);
|
||||
}
|
||||
|
||||
time_t input = 1531461823;
|
||||
fputs(ctime(&input), stdout); // Omit newline
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
int check(time_t input) {
|
||||
struct tm* t = localtime(&input);
|
||||
|
||||
printf("%ld = %ld\n", input, mktime(t));
|
||||
|
||||
if (input != mktime(t)) {
|
||||
printf(
|
||||
"Year %d, Day of year: %d, Month %d, Day of month: %d, Day of week: %d, %d:%d:%d\n",
|
||||
t->tm_year, t->tm_yday, t->tm_mon, t->tm_mday, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec
|
||||
);
|
||||
puts("Failed!");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int main() {
|
||||
struct tm t = {};
|
||||
|
||||
t.tm_year = 71;
|
||||
t.tm_mday = 1;
|
||||
|
||||
printf("%ld\n", mktime(&t));
|
||||
|
||||
int day = 60 * 60 * 24;
|
||||
time_t inputs[] = { -(day * 33), -day, -500, 0, 1531454950 };
|
||||
for (int i = 0; i < 5; i += 1) {
|
||||
if (check(inputs[i])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (int i = 0; i < 10; i += 1) {
|
||||
time_t input = (time_t) rand();
|
||||
struct tm* time = localtime(&input);
|
||||
time_t output = mktime(time);
|
||||
if (input != output) {
|
||||
// asctime has newline
|
||||
printf("Comparison %ld == %ld failed. Time: %s", input, output, asctime(time));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user