wchar support

This commit is contained in:
Stephan Vedder
2018-07-01 20:59:37 +02:00
committed by jD91mZM2
parent fb09b03acf
commit cc210361d6
34 changed files with 840 additions and 669 deletions
Generated
+16 -2
View File
@@ -304,6 +304,7 @@ dependencies = [
"sys_wait 0.1.0",
"time 0.1.0",
"unistd 0.1.0",
"wchar 0.1.0",
"wctype 0.1.0",
]
@@ -403,7 +404,7 @@ dependencies = [
"errno 0.1.0",
"fcntl 0.1.0",
"platform 0.1.0",
"stdlib 0.1.0",
"ralloc 1.0.0",
"string 0.1.0",
"va_list 0.1.0",
]
@@ -419,6 +420,7 @@ dependencies = [
"ralloc 1.0.0",
"rand 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.0",
"wchar 0.1.0",
]
[[package]]
@@ -428,7 +430,7 @@ dependencies = [
"cbindgen 0.5.2",
"errno 0.1.0",
"platform 0.1.0",
"stdlib 0.1.0",
"ralloc 1.0.0",
]
[[package]]
@@ -606,6 +608,18 @@ name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wchar"
version = "0.1.0"
dependencies = [
"cbindgen 0.5.2",
"errno 0.1.0",
"platform 0.1.0",
"stdio 0.1.0",
"time 0.1.0",
"va_list 0.1.0",
]
[[package]]
name = "wctype"
version = "0.1.0"
+1
View File
@@ -39,6 +39,7 @@ sys_utsname = { path = "src/sys_utsname" }
sys_wait = { path = "src/sys_wait" }
time = { path = "src/time" }
unistd = { path = "src/unistd" }
wchar = { path = "src/wchar" }
wctype = { path = "src/wctype" }
[dependencies.compiler_builtins]
+5 -2
View File
@@ -1,7 +1,10 @@
#ifndef _BITS_WCHAR_H
#define _BITS_WCHAR_H
#include <stdint.h>
typedef signed short wchar_t;
typedef signed int wint_t;
#define WEOF (0xFFFFFFFFu)
typedef int32_t wchar_t;
typedef uint32_t wint_t;
#endif /* _BITS_WCHAR_H */
+2 -1
View File
@@ -1,11 +1,12 @@
#ifndef _STDDEF_H
#define _STDDEF_H
#include <stdint.h>
#define NULL 0
typedef signed long long ptrdiff_t;
typedef unsigned char wchar_t;
typedef int32_t wchar_t;
typedef unsigned long long size_t;
+332 -95
View File
@@ -1,130 +1,367 @@
/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of GCC.
GCC 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 3, or (at your option)
any later version.
GCC 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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/*
* ISO C Standard: 7.18 Integer types <stdint.h>
*/
#ifndef _STDINT_H
#define _STDINT_H
#define INT8_C(value) ((int8_t) value)
#define INT8_MIN -0x80
#define INT8_MAX 0x7F
typedef signed char int8_t;
/* 7.8.1.1 Exact-width integer types */
#define INT_LEAST8_MIN -0x80
#define INT_LEAST8_MAX 0x7F
typedef signed char int_least8_t;
#ifdef __INT8_TYPE__
typedef __INT8_TYPE__ int8_t;
#endif
#ifdef __INT16_TYPE__
typedef __INT16_TYPE__ int16_t;
#endif
#ifdef __INT32_TYPE__
typedef __INT32_TYPE__ int32_t;
#endif
#ifdef __INT64_TYPE__
typedef __INT64_TYPE__ int64_t;
#endif
#ifdef __UINT8_TYPE__
typedef __UINT8_TYPE__ uint8_t;
#endif
#ifdef __UINT16_TYPE__
typedef __UINT16_TYPE__ uint16_t;
#endif
#ifdef __UINT32_TYPE__
typedef __UINT32_TYPE__ uint32_t;
#endif
#ifdef __UINT64_TYPE__
typedef __UINT64_TYPE__ uint64_t;
#endif
#define INT_FAST8_MIN -0x80
#define INT_FAST8_MAX 0x7F
typedef signed char int_fast8_t;
/* 7.8.1.2 Minimum-width integer types */
#define UINT8_C(value) ((uint8_t) value ## U)
#define UINT8_MIN 0x00
#define UINT8_MAX 0xFF
typedef unsigned char uint8_t;
typedef __INT_LEAST8_TYPE__ int_least8_t;
typedef __INT_LEAST16_TYPE__ int_least16_t;
typedef __INT_LEAST32_TYPE__ int_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
#define UINT_LEAST8_MIN 0x00
#define UINT_LEAST8_MAX 0xFF
typedef unsigned char uint_least8_t;
/* 7.8.1.3 Fastest minimum-width integer types */
#define UINT_FAST8_MIN 0x00
#define UINT_FAST8_MAX 0xFF
typedef unsigned char uint_fast8_t;
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define INT16_C(value) value
#define INT16_MIN -0x8000
#define INT16_MAX 0x7FFF
typedef signed short int16_t;
/* 7.8.1.4 Integer types capable of holding object pointers */
#define INT_LEAST16_MIN -0x8000
#define INT_LEAST16_MAX 0x7FFF
typedef signed short int_least16_t;
#ifdef __INTPTR_TYPE__
typedef __INTPTR_TYPE__ intptr_t;
#endif
#ifdef __UINTPTR_TYPE__
typedef __UINTPTR_TYPE__ uintptr_t;
#endif
#define INT_FAST16_MIN -0x8000
#define INT_FAST16_MAX 0x7FFF
typedef signed short int_fast16_t;
/* 7.8.1.5 Greatest-width integer types */
#define UINT16_C(value) value ## U
#define UINT16_MIN 0x0000
#define UINT16_MAX 0xFFFF
typedef unsigned short uint16_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
#define UINT_LEAST16_MIN 0x0000
#define UINT_LEAST16_MAX 0xFFFF
typedef unsigned short uint_least16_t;
#if (!defined __cplusplus || __cplusplus >= 201103L \
|| defined __STDC_LIMIT_MACROS)
#define UINT_FAST16_MIN 0x0000
#define UINT_FAST16_MAX 0xFFFF
typedef unsigned short uint_fast16_t;
/* 7.18.2 Limits of specified-width integer types */
#define INT32_C(value) value ## L
#define INT32_MIN -0x80000000
#define INT32_MAX 0x7FFFFFFF
typedef signed long int32_t;
#ifdef __INT8_MAX__
# undef INT8_MAX
# define INT8_MAX __INT8_MAX__
# undef INT8_MIN
# define INT8_MIN (-INT8_MAX - 1)
#endif
#ifdef __UINT8_MAX__
# undef UINT8_MAX
# define UINT8_MAX __UINT8_MAX__
#endif
#ifdef __INT16_MAX__
# undef INT16_MAX
# define INT16_MAX __INT16_MAX__
# undef INT16_MIN
# define INT16_MIN (-INT16_MAX - 1)
#endif
#ifdef __UINT16_MAX__
# undef UINT16_MAX
# define UINT16_MAX __UINT16_MAX__
#endif
#ifdef __INT32_MAX__
# undef INT32_MAX
# define INT32_MAX __INT32_MAX__
# undef INT32_MIN
# define INT32_MIN (-INT32_MAX - 1)
#endif
#ifdef __UINT32_MAX__
# undef UINT32_MAX
# define UINT32_MAX __UINT32_MAX__
#endif
#ifdef __INT64_MAX__
# undef INT64_MAX
# define INT64_MAX __INT64_MAX__
# undef INT64_MIN
# define INT64_MIN (-INT64_MAX - 1)
#endif
#ifdef __UINT64_MAX__
# undef UINT64_MAX
# define UINT64_MAX __UINT64_MAX__
#endif
#define INT_LEAST32_MIN -0x80000000
#define INT_LEAST32_MAX 0x7FFFFFFF
typedef signed long int_least32_t;
#undef INT_LEAST8_MAX
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
#undef INT_LEAST8_MIN
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
#undef UINT_LEAST8_MAX
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
#undef INT_LEAST16_MAX
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
#undef INT_LEAST16_MIN
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
#undef UINT_LEAST16_MAX
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
#undef INT_LEAST32_MAX
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
#undef INT_LEAST32_MIN
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
#undef UINT_LEAST32_MAX
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
#undef INT_LEAST64_MAX
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
#undef INT_LEAST64_MIN
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
#undef UINT_LEAST64_MAX
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
#define INT_FAST32_MIN -0x80000000
#define INT_FAST32_MAX 0x7FFFFFFF
typedef signed long int_fast32_t;
#undef INT_FAST8_MAX
#define INT_FAST8_MAX __INT_FAST8_MAX__
#undef INT_FAST8_MIN
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
#undef UINT_FAST8_MAX
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
#undef INT_FAST16_MAX
#define INT_FAST16_MAX __INT_FAST16_MAX__
#undef INT_FAST16_MIN
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
#undef UINT_FAST16_MAX
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
#undef INT_FAST32_MAX
#define INT_FAST32_MAX __INT_FAST32_MAX__
#undef INT_FAST32_MIN
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
#undef UINT_FAST32_MAX
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
#undef INT_FAST64_MAX
#define INT_FAST64_MAX __INT_FAST64_MAX__
#undef INT_FAST64_MIN
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
#undef UINT_FAST64_MAX
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
#define UINT32_C(value) value ## UL
#define UINT32_MIN 0x00000000
#define UINT32_MAX 0xFFFFFFFF
typedef unsigned long uint32_t;
#ifdef __INTPTR_MAX__
# undef INTPTR_MAX
# define INTPTR_MAX __INTPTR_MAX__
# undef INTPTR_MIN
# define INTPTR_MIN (-INTPTR_MAX - 1)
#endif
#ifdef __UINTPTR_MAX__
# undef UINTPTR_MAX
# define UINTPTR_MAX __UINTPTR_MAX__
#endif
#define UINT_LEAST32_MIN 0x00000000
#define UINT_LEAST32_MAX 0xFFFFFFFF
typedef unsigned long uint_least32_t;
#undef INTMAX_MAX
#define INTMAX_MAX __INTMAX_MAX__
#undef INTMAX_MIN
#define INTMAX_MIN (-INTMAX_MAX - 1)
#undef UINTMAX_MAX
#define UINTMAX_MAX __UINTMAX_MAX__
#define UINT_FAST32_MIN 0x00000000
#define UINT_FAST32_MAX 0xFFFFFFFF
typedef unsigned long uint_fast32_t;
/* 7.18.3 Limits of other integer types */
#define INT64_C(value) value ## LL
#define INT64_MIN -0x8000000000000000
#define INT64_MAX 0x7FFFFFFFFFFFFFFF
typedef signed long long int64_t;
#undef PTRDIFF_MAX
#define PTRDIFF_MAX __PTRDIFF_MAX__
#undef PTRDIFF_MIN
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
#define INT_LEAST64_MIN -0x8000000000000000
#define INT_LEAST64_MAX 0x7FFFFFFFFFFFFFFF
typedef signed long long int_least64_t;
#undef SIG_ATOMIC_MAX
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#undef SIG_ATOMIC_MIN
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
#define INT_FAST64_MIN -0x8000000000000000
#define INT_FAST64_MAX 0x7FFFFFFFFFFFFFFF
typedef signed long long int_fast64_t;
#undef SIZE_MAX
#define SIZE_MAX __SIZE_MAX__
#define UINT64_C(value) value ## ULL
#define UINT64_MIN 0x0000000000000000
#define UINT64_MAX 0xFFFFFFFFFFFFFFFF
typedef unsigned long long uint64_t;
#undef WCHAR_MAX
#define WCHAR_MAX __WCHAR_MAX__
#undef WCHAR_MIN
#define WCHAR_MIN __WCHAR_MIN__
#define UINT_LEAST64_MIN 0x0000000000000000
#define UINT_LEAST64_MAX 0xFFFFFFFFFFFFFFFF
typedef unsigned long long uint_least64_t;
#undef WINT_MAX
#define WINT_MAX __WINT_MAX__
#undef WINT_MIN
#define WINT_MIN __WINT_MIN__
#define UINT_FAST64_MIN 0x0000000000000000
#define UINT_FAST64_MAX 0xFFFFFFFFFFFFFFFF
typedef unsigned long long uint_fast64_t;
#endif /* (!defined __cplusplus || __cplusplus >= 201103L
|| defined __STDC_LIMIT_MACROS) */
#define INTMAX_C(value) value ## LL
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
typedef int64_t intmax_t;
#if (!defined __cplusplus || __cplusplus >= 201103L \
|| defined __STDC_CONSTANT_MACROS)
#define UINTMAX_C(value) value ## ULL
#define UINTMAX_MIN UINT64_MIN
#define UINTMAX_MAX UINT64_MAX
typedef uint64_t uintmax_t;
#undef INT8_C
#define INT8_C(c) __INT8_C(c)
#undef INT16_C
#define INT16_C(c) __INT16_C(c)
#undef INT32_C
#define INT32_C(c) __INT32_C(c)
#undef INT64_C
#define INT64_C(c) __INT64_C(c)
#undef UINT8_C
#define UINT8_C(c) __UINT8_C(c)
#undef UINT16_C
#define UINT16_C(c) __UINT16_C(c)
#undef UINT32_C
#define UINT32_C(c) __UINT32_C(c)
#undef UINT64_C
#define UINT64_C(c) __UINT64_C(c)
#undef INTMAX_C
#define INTMAX_C(c) __INTMAX_C(c)
#undef UINTMAX_C
#define UINTMAX_C(c) __UINTMAX_C(c)
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
typedef int64_t intptr_t;
#endif /* (!defined __cplusplus || __cplusplus >= 201103L
|| defined __STDC_CONSTANT_MACROS) */
#define UINTPTR_MIN UINT64_MIN
#define UINTPTR_MAX UINT64_MAX
typedef uint64_t uintptr_t;
#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* TS 18661-1 widths of integer types. */
#ifdef __INT8_TYPE__
# undef INT8_WIDTH
# define INT8_WIDTH 8
#endif
#ifdef __UINT8_TYPE__
# undef UINT8_WIDTH
# define UINT8_WIDTH 8
#endif
#ifdef __INT16_TYPE__
# undef INT16_WIDTH
# define INT16_WIDTH 16
#endif
#ifdef __UINT16_TYPE__
# undef UINT16_WIDTH
# define UINT16_WIDTH 16
#endif
#ifdef __INT32_TYPE__
# undef INT32_WIDTH
# define INT32_WIDTH 32
#endif
#ifdef __UINT32_TYPE__
# undef UINT32_WIDTH
# define UINT32_WIDTH 32
#endif
#ifdef __INT64_TYPE__
# undef INT64_WIDTH
# define INT64_WIDTH 64
#endif
#ifdef __UINT64_TYPE__
# undef UINT64_WIDTH
# define UINT64_WIDTH 64
#endif
#undef INT_LEAST8_WIDTH
#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef UINT_LEAST8_WIDTH
#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef INT_LEAST16_WIDTH
#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef UINT_LEAST16_WIDTH
#define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef INT_LEAST32_WIDTH
#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef UINT_LEAST32_WIDTH
#define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef INT_LEAST64_WIDTH
#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef UINT_LEAST64_WIDTH
#define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef INT_FAST8_WIDTH
#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef UINT_FAST8_WIDTH
#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef INT_FAST16_WIDTH
#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef UINT_FAST16_WIDTH
#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef INT_FAST32_WIDTH
#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef UINT_FAST32_WIDTH
#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef INT_FAST64_WIDTH
#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__
#undef UINT_FAST64_WIDTH
#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__
#ifdef __INTPTR_TYPE__
# undef INTPTR_WIDTH
# define INTPTR_WIDTH __INTPTR_WIDTH__
#endif
#ifdef __UINTPTR_TYPE__
# undef UINTPTR_WIDTH
# define UINTPTR_WIDTH __INTPTR_WIDTH__
#endif
#undef INTMAX_WIDTH
#define INTMAX_WIDTH __INTMAX_WIDTH__
#undef UINTMAX_WIDTH
#define UINTMAX_WIDTH __INTMAX_WIDTH__
#undef PTRDIFF_WIDTH
#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
#undef SIG_ATOMIC_WIDTH
#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
#undef SIZE_WIDTH
#define SIZE_WIDTH __SIZE_WIDTH__
#undef WCHAR_WIDTH
#define WCHAR_WIDTH __WCHAR_WIDTH__
#undef WINT_WIDTH
#define WINT_WIDTH __WINT_WIDTH__
#define SIZE_MAX UINT64_MAX
#endif
typedef long sig_atomic_t;
#endif /* _STDINT_H */
#endif /* _GCC_STDINT_H */
+1
View File
@@ -29,6 +29,7 @@ pub extern crate sys_utsname;
pub extern crate sys_wait;
pub extern crate time;
pub extern crate unistd;
pub extern crate wchar;
pub extern crate wctype;
#[cfg(not(any(test, target_os = "redox")))]
+2 -2
View File
@@ -44,8 +44,8 @@ pub type c_char = i8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type wchar_t = i16;
pub type wint_t = i32;
pub type wchar_t = i32;
pub type wint_t = u32;
pub type wctype_t = i64;
pub type off_t = i64;
+1 -1
View File
@@ -12,5 +12,5 @@ platform = { path = "../platform" }
va_list = { path = "../../va_list", features = ["no_std"] }
fcntl = { path = "../fcntl" }
string = { path = "../string" }
stdlib = { path = "../stdlib" }
ralloc = { path = "../../ralloc", default-features = false }
errno = { path = "../errno"}
+2 -2
View File
@@ -1,5 +1,5 @@
use super::{internal, BUFSIZ, FILE, UNGET};
use stdlib::calloc;
use ralloc;
use core::{mem, ptr};
use core::sync::atomic::AtomicBool;
use platform::types::*;
@@ -62,7 +62,7 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> *mut FILE {
flags |= F_APP;
}
let file = calloc(mem::size_of::<FILE>() + BUFSIZ + UNGET, 1) as *mut FILE;
let file = ralloc::alloc(mem::size_of::<FILE>() + BUFSIZ + UNGET, 1) as *mut FILE;
// Allocate the file
(*file) = FILE {
flags: flags,
+16 -10
View File
@@ -8,12 +8,11 @@ extern crate alloc;
extern crate errno;
extern crate fcntl;
extern crate platform;
extern crate stdlib;
extern crate ralloc;
extern crate string;
extern crate va_list as vl;
use core::str;
use core::ptr;
use core::{str,ptr,mem};
use core::fmt::{self, Error, Result};
use core::fmt::Write as WriteFmt;
use core::sync::atomic::{AtomicBool, Ordering};
@@ -23,8 +22,8 @@ use platform::{c_str, errno, Read, Write};
use errno::STR_ERROR;
use vl::VaList as va_list;
mod scanf;
mod printf;
mod scanf;
mod default;
pub use default::*;
@@ -219,13 +218,16 @@ pub extern "C" fn cuserid(s: *mut c_char) -> *mut c_char {
/// prior to using this function.
#[no_mangle]
pub extern "C" fn fclose(stream: &mut FILE) -> c_int {
use stdlib::free;
use ralloc::free;
flockfile(stream);
let r = helpers::fflush_unlocked(stream) | platform::close(stream.fd);
if stream.flags & constants::F_PERM == 0 {
// Not one of stdin, stdout or stderr
unsafe {
free(stream as *mut _ as *mut _);
free(
stream as *mut _ as *mut _,
mem::size_of::<FILE>() + BUFSIZ + UNGET,
);
}
}
r
@@ -720,7 +722,7 @@ pub extern "C" fn putc_unlocked(c: c_int, stream: &mut FILE) -> c_int {
c
}
} else {
if stream.wend.is_null() && stream.can_write() {
if stream.wend.is_null() && !stream.can_write() {
-1
} else if c as i8 != stream.buf_char && stream.wpos < stream.wend {
unsafe {
@@ -808,10 +810,10 @@ pub unsafe extern "C" fn setvbuf(
size: usize,
) -> c_int {
// TODO: Check correctness
use stdlib::calloc;
use ralloc::alloc;
let mut buf = buf;
if buf.is_null() && mode != _IONBF {
buf = calloc(size, 1) as *mut c_char;
buf = alloc(size, 1) as *mut c_char;
}
(*stream).buf_size = size;
(*stream).buf_char = -1;
@@ -907,5 +909,9 @@ pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int {
#[no_mangle]
pub unsafe extern "C" fn vsscanf(s: *const c_char, format: *const c_char, ap: va_list) -> c_int {
scanf::scanf(&mut platform::UnsafeStringReader(s as *const u8), format, ap)
scanf::scanf(
&mut platform::UnsafeStringReader(s as *const u8),
format,
ap,
)
}
+2
View File
@@ -14,3 +14,5 @@ ctype = { path = "../ctype" }
errno = { path = "../errno" }
rand = { version = "0.5.2", default-features = false }
time = { path = "../time" }
wchar = { path = "../wchar" }
string = { path = "../string" }
+62 -42
View File
@@ -9,12 +9,16 @@ extern crate platform;
extern crate ralloc;
extern crate rand;
extern crate time;
extern crate wchar;
extern crate string;
use core::{ptr, str};
use rand::{Rng, SeedableRng};
use rand::{Rng, SeedableRng};
use rand::rngs::JitterRng;
use rand::prng::XorShiftRng;
use rand::distributions::Alphanumeric;
use wchar::*;
use string::*;
use errno::*;
use platform::types::*;
@@ -28,6 +32,11 @@ pub const EXIT_FAILURE: c_int = 1;
pub const EXIT_SUCCESS: c_int = 0;
pub const RAND_MAX: c_int = 2147483647;
//Maximum number of bytes in a multibyte character for the current locale
pub const MB_CUR_MAX: c_int = 4;
//Maximum number of bytes in a multibyte characters for any locale
pub const MB_LEN_MAX: c_int = 4;
static mut ATEXIT_FUNCS: [Option<extern "C" fn()>; 32] = [None; 32];
static mut RNG: Option<XorShiftRng> = None;
@@ -101,7 +110,7 @@ pub unsafe extern "C" fn atof(s: *const c_char) -> c_double {
}
macro_rules! dec_num_from_ascii {
($s: expr, $t: ty) => {
($s:expr, $t:ty) => {
unsafe {
let mut s = $s;
// Iterate past whitespace
@@ -351,8 +360,19 @@ pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_voi
}
#[no_mangle]
pub extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int {
unimplemented!();
pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int {
let mut wc : wchar_t = 0;
let mut state : mbstate_t = mbstate_t { };
let result : usize = mbrtowc(&mut wc, s, n, &mut state);
if result == -1isize as usize {
return -1;
}
if result == -2isize as usize {
return -1;
}
result as i32
}
#[no_mangle]
@@ -370,16 +390,13 @@ pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
use core::slice;
use core::iter;
use core::mem;
extern "C" {
fn strlen(s: *const c_char) -> size_t;
}
let len = unsafe { strlen(name) };
if len < 6 {
unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 };
return name;
}
for i in len-6..len {
for i in len - 6..len {
if unsafe { *name.offset(i as isize) } != b'X' as c_char {
unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 };
@@ -392,11 +409,9 @@ pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
let mut retries = 100;
loop {
let mut char_iter = iter::repeat(())
.map(|()| rng.sample(Alphanumeric))
.take(6);
let mut char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6);
unsafe {
for (i,c) in char_iter.enumerate() {
for (i, c) in char_iter.enumerate() {
*name.offset(len as isize - i as isize - 1) = c as c_char
}
}
@@ -404,13 +419,17 @@ pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
unsafe {
let mut st: stat = mem::uninitialized();
if platform::stat(name, &mut st) != 0 {
if platform::errno != ENOENT { *name = 0; }
if platform::errno != ENOENT {
*name = 0;
}
return name;
}
mem::forget(st);
}
retries = retries -1;
if retries == 0 { break; }
retries = retries - 1;
if retries == 0 {
break;
}
}
unsafe { platform::errno = EEXIST };
unsafe { *name = 0 };
@@ -421,11 +440,10 @@ fn get_nstime() -> u64 {
use core::mem;
use time::constants::CLOCK_MONOTONIC;
let mut ts: timespec = unsafe { mem::uninitialized() };
platform::clock_gettime(CLOCK_MONOTONIC, &mut ts);
platform::clock_gettime(CLOCK_MONOTONIC, &mut ts);
unsafe { ts.tv_nsec as u64 }
}
#[no_mangle]
pub extern "C" fn mkstemp(name: *mut c_char) -> c_int {
unimplemented!();
@@ -639,7 +657,8 @@ pub fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, isize,
if val == -1 || val as c_int >= base {
break;
} else {
if let Some(res) = num.checked_mul(base as c_ulong)
if let Some(res) = num
.checked_mul(base as c_ulong)
.and_then(|num| num.checked_add(val as c_ulong))
{
num = res;
@@ -665,13 +684,7 @@ pub fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, isize,
#[macro_export]
macro_rules! strto_impl {
(
$rettype:ty,
$signed:expr,
$maxval:expr,
$minval:expr,
$s:ident,
$endptr:ident,
$base:ident
$rettype:ty, $signed:expr, $maxval:expr, $minval:expr, $s:ident, $endptr:ident, $base:ident
) => {{
// ensure these are constants
const CHECK_SIGN: bool = $signed;
@@ -721,9 +734,8 @@ macro_rules! strto_impl {
// convert the string to a number
let num_str = $s.offset(idx);
let res = match $base {
0 => detect_base(num_str).and_then(|($base, i)| {
convert_integer(num_str.offset(i), $base)
}),
0 => detect_base(num_str)
.and_then(|($base, i)| convert_integer(num_str.offset(i), $base)),
8 => convert_octal(num_str),
16 => convert_hex(num_str),
_ => convert_integer(num_str, $base),
@@ -770,15 +782,15 @@ macro_rules! strto_impl {
set_endptr(idx);
num
}}
}};
}
#[no_mangle]
pub unsafe extern "C" fn strtoul(s: *const c_char,
endptr: *mut *mut c_char,
base: c_int)
-> c_ulong {
pub unsafe extern "C" fn strtoul(
s: *const c_char,
endptr: *mut *mut c_char,
base: c_int,
) -> c_ulong {
strto_impl!(
c_ulong,
false,
@@ -791,10 +803,7 @@ pub unsafe extern "C" fn strtoul(s: *const c_char,
}
#[no_mangle]
pub unsafe extern "C" fn strtol(s: *const c_char,
endptr: *mut *mut c_char,
base: c_int)
-> c_long {
pub unsafe extern "C" fn strtol(s: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long {
strto_impl!(
c_long,
true,
@@ -835,11 +844,22 @@ pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void {
}
#[no_mangle]
pub extern "C" fn wcstombs(s: *mut c_char, pwcs: *const wchar_t, n: size_t) -> size_t {
unimplemented!();
pub extern "C" fn wcstombs(s: *mut c_char, pwcs: *mut *const wchar_t, n: size_t) -> size_t {
let mut state: mbstate_t = mbstate_t {};
wcsrtombs(s, pwcs, n, &mut state)
}
#[no_mangle]
pub extern "C" fn wctomb(s: *mut c_char, wchar: wchar_t) -> c_int {
unimplemented!();
pub unsafe extern "C" fn wctomb(s: *mut c_char, wc: wchar_t) -> c_int {
let mut state : mbstate_t = mbstate_t {};
let result: usize = wcrtomb(s, wc, &mut state);
if result == -1isize as usize {
return -1;
}
if result == -2isize as usize {
return -1;
}
result as c_int
}
+1 -1
View File
@@ -9,5 +9,5 @@ cbindgen = { path = "../../cbindgen" }
[dependencies]
platform = { path = "../platform" }
stdlib = { path = "../stdlib" }
ralloc = { path = "../../ralloc", default-features = false }
errno = { path = "../errno" }
+2 -3
View File
@@ -1,10 +1,9 @@
//! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html
#![no_std]
extern crate errno;
extern crate platform;
extern crate stdlib;
extern crate ralloc;
use platform::types::*;
use errno::*;
@@ -193,7 +192,7 @@ pub unsafe extern "C" fn strndup(s1: *const c_char, size: usize) -> *mut c_char
let len = strnlen(s1, size);
// the "+ 1" is to account for the NUL byte
let buffer = stdlib::malloc(len + 1) as *mut c_char;
let buffer = ralloc::alloc(len + 1, 1) as *mut c_char;
if buffer.is_null() {
platform::errno = ENOMEM as c_int;
} else {
-377
View File
@@ -1,377 +0,0 @@
pub type wchar_t = libc::c_int;
pub type wint_t = libc::c_uint;
#[no_mangle]
pub extern "C" fn btowc(c: libc::c_int) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fwprintf(stream: *mut FILE, format: *const wchar_t, ...)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fwscanf(stream: *mut FILE, format: *const wchar_t, ...)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswalnum(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswalpha(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswcntrl(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswdigit(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswgraph(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswlower(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswprint(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswpunct(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswspace(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswupper(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn iswxdigit(wc: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fgetws(ws: *mut wchar_t, n: libc::c_int,
stream: *mut FILE) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fputwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fwide(stream: *mut FILE, mode: libc::c_int)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn getwc(stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn getwchar() -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn mbsinit(ps: *const mbstate_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn mbrlen(s: *const libc::c_char, n: usize,
ps: *mut mbstate_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn mbrtowc(pwc: *mut wchar_t, s: *const libc::c_char,
n: usize, ps: *mut mbstate_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn mbsrtowcs(dst: *mut wchar_t,
src: *mut *const libc::c_char, len: usize,
ps: *mut mbstate_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn putwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn putwchar(wc: wchar_t) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn swprintf(s: *mut wchar_t, n: usize,
format: *const wchar_t, ...) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn swscanf(s: *const wchar_t, format: *const wchar_t, ...)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn towlower(wc: wint_t) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn towupper(wc: wint_t) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn ungetwc(wc: wint_t, stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vfwprintf(stream: *mut FILE, format: *const wchar_t,
arg: va_list) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vwprintf(format: *const wchar_t, arg: va_list)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vswprintf(s: *mut wchar_t, n: usize, format: *const wchar_t,
arg: va_list) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcrtomb(s: *mut libc::c_char, wc: wchar_t,
ps: *mut mbstate_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcscat(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcschr(ws1: *const wchar_t, ws2: wchar_t)
-> *mut libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcscmp(ws1: *const wchar_t, ws2: *const wchar_t)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcscoll(ws1: *const wchar_t, ws2: *const wchar_t)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcscpy(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcscspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsftime(wcs: *mut wchar_t, maxsize: usize, format: *const wchar_t,
timptr: *mut tm) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcslen(ws: *const wchar_t) -> libc::c_ulong {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsncat(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsncmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsncpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcspbrk(ws1: *const wchar_t, ws2: *const wchar_t)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsrchr(ws1: *const wchar_t, ws2: wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsrtombs(dst: *mut libc::c_char,
src: *mut *const wchar_t, len: usize,
ps: *mut mbstate_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcstod(nptr: *const wchar_t, endptr: *mut *mut wchar_t) -> f64 {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcstok(ws1: *mut wchar_t, ws2: *const wchar_t,
ptr: *mut *mut wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcstol(nptr: *const wchar_t, endptr: *mut *mut wchar_t,
base: libc::c_int) -> libc::c_long {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcstoul(nptr: *const wchar_t, endptr: *mut *mut wchar_t,
base: libc::c_int) -> libc::c_ulong {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcswidth(pwcs: *const wchar_t, n: usize)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize)
-> usize {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wctob(c: wint_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wcwidth(wc: wchar_t) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: usize)
-> *mut libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wmemcmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize)
-> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wmemcpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wmemmove(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wmemset(ws1: *mut wchar_t, ws2: wchar_t, n: usize)
-> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wprintf(format: *const wchar_t, ...) -> libc::c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wscanf(format: *const wchar_t, ...) -> libc::c_int {
unimplemented!();
}
+18
View File
@@ -0,0 +1,18 @@
[package]
name = "wchar"
version = "0.1.0"
authors = ["Stephan Vedder <stephan.vedder@gmail.com>"]
build = "build.rs"
[build-dependencies]
cbindgen = { path = "../../cbindgen" }
[features]
str_internals = []
[dependencies]
platform = { path = "../platform" }
stdio = { path = "../stdio" }
errno = { path = "../errno" }
time = { path = "../time" }
va_list = { path = "../../va_list", features = ["no_std"] }
+11
View File
@@ -0,0 +1,11 @@
extern crate cbindgen;
use std::{env, fs};
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
fs::create_dir_all("../../target/include").expect("failed to create include directory");
cbindgen::generate(crate_dir)
.expect("failed to generate bindings")
.write_to_file("../../target/include/wchar.h");
}
+7
View File
@@ -0,0 +1,7 @@
sys_includes = ["stddef.h", "stdint.h", "time.h", "stdio.h" ]
include_guard = "_WCHAR_H"
header = "#include <bits/wchar.h>"
language = "C"
[enum]
prefix_with_name = true
+183 -130
View File
@@ -1,55 +1,84 @@
//! wchar implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html
//! wchar implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/wchar.h.html
#![no_std]
#![feature(str_internals)]
extern crate errno;
extern crate platform;
extern crate stdlib;
extern crate string;
extern crate stdio;
extern crate time;
extern crate va_list as vl;
use platform::types::*;
use errno::*;
use time::*;
use core::cmp;
use core::usize;
use core::ptr;
use core::mem;
use string::*;
use stdio::*;
use vl::VaList as va_list;
pub type wint_t = i32;
mod utf8;
const WEOF: wint_t = 0xFFFFFFFFu32;
//Maximum number of bytes in a multibyte character for the current locale
const MB_CUR_MAX: c_int = 4;
//Maximum number of bytes in a multibyte characters for any locale
const MB_LEN_MAX: c_int = 4;
#[repr(C)]
pub struct mbstate_t {
pub mbs_count: c_int,
pub mbs_length: c_int,
pub mbs_wch: wint_t,
}
#[derive(Clone, Copy)]
pub struct mbstate_t {}
#[no_mangle]
pub unsafe extern "C" fn btowc(c: c_int) -> wint_t {
//Check for EOF
if c == -1 {
return -1;
if c as wint_t == WEOF {
return WEOF;
}
let uc = c as u8;
let c = uc as c_char;
let mut ps: mbstate_t = mbstate_t {
mbs_count: 0,
mbs_length: 0,
mbs_wch: 0,
};
let mut ps: mbstate_t = mbstate_t {};
let mut wc: wchar_t = 0;
let saved_errno = platform::errno;
let status = mbrtowc(&mut wc, &c as (*const c_char), 1, &mut ps);
if status == usize::max_value() || status == usize::max_value() - 1 {
platform::errno = saved_errno;
return platform::errno;
return WEOF;
}
return wc as wint_t;
}
#[no_mangle]
pub unsafe extern "C" fn fputwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
//Convert wchar_t to multibytes first
static mut INTERNAL: mbstate_t = mbstate_t {};
let mut bytes: [c_char; MB_CUR_MAX as usize] = [0; MB_CUR_MAX as usize];
let amount = wcrtomb(bytes.as_mut_ptr(), wc, &mut INTERNAL);
for i in 0..amount {
fputc(bytes[i] as c_int, &mut *stream);
}
wc as wint_t
}
#[no_mangle]
pub extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn getwc(stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn getwchar() -> wint_t {
unimplemented!();
@@ -57,24 +86,21 @@ pub extern "C" fn getwchar() -> wint_t {
#[no_mangle]
pub unsafe extern "C" fn mbsinit(ps: *const mbstate_t) -> c_int {
if ps.is_null() || (*ps).mbs_count == 0 {
return 1;
//Add a check for the state maybe
if ps.is_null() {
1
} else {
return 0;
0
}
}
#[no_mangle]
pub unsafe extern "C" fn mbrlen(s: *const c_char, n: usize, ps: *mut mbstate_t) -> usize {
static mut internal: mbstate_t = mbstate_t {
mbs_count: 0,
mbs_length: 0,
mbs_wch: 0,
};
return mbrtowc(ptr::null_mut(), s, n, &mut internal);
static mut INTERNAL: mbstate_t = mbstate_t {};
mbrtowc(ptr::null_mut(), s, n, &mut INTERNAL)
}
//Only works for utf8!
//Only works for UTF8 at the moment
#[no_mangle]
pub unsafe extern "C" fn mbrtowc(
pwc: *mut wchar_t,
@@ -82,123 +108,85 @@ pub unsafe extern "C" fn mbrtowc(
n: usize,
ps: *mut mbstate_t,
) -> usize {
static mut internal: mbstate_t = mbstate_t {
mbs_count: 0,
mbs_length: 0,
mbs_wch: 0,
};
static mut INTERNAL: mbstate_t = mbstate_t {};
if ps.is_null() {
let ps = &mut internal;
let ps = &mut INTERNAL;
}
if s.is_null() {
let xs: [c_char; 1] = [0];
utf8_mbrtowc(pwc, &xs[0] as *const c_char, 1, ps);
return utf8::mbrtowc(pwc, &xs[0] as *const c_char, 1, ps);
} else {
return utf8::mbrtowc(pwc, s, n, ps);
}
return utf8_mbrtowc(pwc, s, n, ps);
}
//Convert a multibyte string to a wide string with a limited amount of bytes
//Required for in POSIX.1-2008
#[no_mangle]
unsafe extern "C" fn utf8_mbrtowc(
pwc: *mut wchar_t,
s: *const c_char,
n: usize,
pub unsafe extern "C" fn mbsnrtowcs(
dst_ptr: *mut wchar_t,
src_ptr: *mut *const c_char,
src_len: usize,
dst_len: usize,
ps: *mut mbstate_t,
) -> usize {
let mut i: usize = 0;
static mut INTERNAL: mbstate_t = mbstate_t {};
while !(i > 0 && (*ps).mbs_count == 0) {
if (n <= i) {
return -2isize as usize;
}
let c = s.offset(i as isize);
let uc = c as u8;
if ps.is_null() {
let ps = &mut INTERNAL;
}
if (*ps).mbs_count == 0 {
//1 byte sequence - 007F
if (uc & 0b10000000) == 0b00000000 {
(*ps).mbs_count = 0;
(*ps).mbs_length = 1;
(*ps).mbs_wch = (uc as wchar_t & 0b1111111) as wint_t;
}
//2 byte sequence - C2DF
else if (uc & 0b11100000) == 0b11000000 {
(*ps).mbs_count = 1;
(*ps).mbs_length = 2;
(*ps).mbs_wch = (uc as wchar_t & 0b11111) as wint_t;
}
//3 byte sequence - E0EF
else if (uc & 0b11110000) == 0b11100000 {
(*ps).mbs_count = 2;
(*ps).mbs_length = 3;
(*ps).mbs_wch = (uc as wchar_t & 0b1111) as wint_t;
}
//4 byte sequence - F0F4
else if (uc & 0b11111000) == 0b11110000 {
(*ps).mbs_count = 3;
(*ps).mbs_length = 4;
(*ps).mbs_wch = (uc as wchar_t & 0b111) as wint_t;
} else {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
} else {
if (uc & 0b11000000) != 0b10000000 {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
let mut src = *src_ptr;
(*ps).mbs_wch = (*ps).mbs_wch << 6 | (uc & 0b00111111) as wint_t;
(*ps).mbs_count -= 1;
let mut dst_offset: usize = 0;
let mut src_offset: usize = 0;
while (dst_ptr.is_null() || dst_offset < dst_len) && src_offset < src_len {
let ps_copy = *ps;
let mut wc: wchar_t = 0;
let amount = mbrtowc(
&mut wc,
src.offset(src_offset as isize),
src_len - src_offset,
ps,
);
// Stop in the event a decoding error occured.
if amount == -1isize as usize {
*src_ptr = src.offset(src_offset as isize);
return 1isize as usize;
}
i += 1;
// Stop decoding early in the event we encountered a partial character.
if amount == -2isize as usize {
*ps = ps_copy;
break;
}
// Store the decoded wide character in the destination buffer.
if !dst_ptr.is_null() {
*dst_ptr.offset(dst_offset as isize) = wc;
}
// Stop decoding after decoding a null character and return a NULL
// source pointer to the caller, not including the null character in the
// number of characters stored in the destination buffer.
if wc == 0 {
src = ptr::null();
src_offset = 0;
break;
}
dst_offset += 1;
src_offset += amount;
}
// Reject the character if it was produced with an overly long sequence.
if (*ps).mbs_length == 1 && 1 << 7 <= (*ps).mbs_wch {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
if (*ps).mbs_length == 2 && 1 << (5 + 1 * 6) <= (*ps).mbs_wch {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
if (*ps).mbs_length == 3 && 1 << (5 + 2 * 6) <= (*ps).mbs_wch {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
if (*ps).mbs_length == 4 && 1 << (5 + 3 * 6) <= (*ps).mbs_wch {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
// The definition of UTF-8 prohibits encoding character numbers between
// U+D800 and U+DFFF, which are reserved for use with the UTF-16 encoding
// form (as surrogate pairs) and do not directly represent characters.
if 0xD800 <= (*ps).mbs_wch && (*ps).mbs_wch <= 0xDFFF {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
// RFC 3629 limits UTF-8 to 0x0 through 0x10FFFF.
if 0x10FFFF <= (*ps).mbs_wch {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
let result: wchar_t = (*ps).mbs_wch as wchar_t;
if !pwc.is_null() {
*pwc = result;
}
(*ps).mbs_length = 0;
(*ps).mbs_wch = 0;
return if result != 0 { i } else { 0 };
*src_ptr = src.offset(src_offset as isize);
return dst_offset;
}
//Convert a multibyte string to a wide string
#[no_mangle]
pub extern "C" fn mbsrtowcs(
dst: *mut wchar_t,
@@ -206,11 +194,31 @@ pub extern "C" fn mbsrtowcs(
len: usize,
ps: *mut mbstate_t,
) -> usize {
unsafe { mbsnrtowcs(dst, src, usize::max_value(), len, ps) }
}
#[no_mangle]
pub unsafe extern "C" fn putwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
fputwc(wc, &mut *stream)
}
#[no_mangle]
pub unsafe extern "C" fn putwchar(wc: wchar_t) -> wint_t {
fputwc(wc, &mut *__stdout())
}
#[no_mangle]
pub extern "C" fn swprintf(
s: *mut wchar_t,
n: usize,
format: *const wchar_t,
mut ap: va_list,
) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn putwchar(wc: wchar_t) -> wint_t {
pub extern "C" fn swscanf(s: *const wchar_t, format: *const wchar_t, mut ap: va_list) -> c_int {
unimplemented!();
}
@@ -225,10 +233,45 @@ pub extern "C" fn towupper(wc: wint_t) -> wint_t {
}
#[no_mangle]
pub extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize {
pub extern "C" fn ungetwc(wc: wint_t, stream: *mut FILE) -> wint_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vfwprintf(stream: *mut FILE, format: *const wchar_t, arg: va_list) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vwprintf(format: *const wchar_t, arg: va_list) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn vswprintf(
s: *mut wchar_t,
n: usize,
format: *const wchar_t,
arg: va_list,
) -> c_int {
unimplemented!();
}
//widechar to multibyte
#[no_mangle]
pub extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize {
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;
if s.is_null() {
wc_cpy = 0;
s_cpy = buffer.as_mut_ptr();
}
unsafe { utf8::wcrtomb(s_cpy, wc_cpy, ps) }
}
#[no_mangle]
pub extern "C" fn wcscat(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
unimplemented!();
@@ -392,3 +435,13 @@ pub extern "C" fn wmemmove(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) ->
pub extern "C" fn wmemset(ws1: *mut wchar_t, ws2: wchar_t, n: usize) -> *mut wchar_t {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wprintf(format: *const wchar_t, mut ap: va_list) -> c_int {
unimplemented!();
}
#[no_mangle]
pub extern "C" fn wscanf(format: *const wchar_t, mut ap: va_list) -> c_int {
unimplemented!();
}
+59
View File
@@ -0,0 +1,59 @@
//UTF implementation parts for wchar.h.
//Partially ported from the Sortix libc
#![no_std]
extern crate errno;
extern crate platform;
use platform::types::*;
use mbstate_t;
use core::{slice,str,usize,char};
//It's guaranteed that we don't have any nullpointers here
pub unsafe fn mbrtowc(pwc: *mut wchar_t, s: *const c_char, n: usize, ps: *mut mbstate_t) -> usize {
let mut size = str::utf8_char_width(*s as u8);
if size > n {
platform::errno = errno::EILSEQ;
return -2isize as usize;
}
if size == 0 {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
let slice = slice::from_raw_parts(s as *const u8, size);
let decoded = str::from_utf8(slice);
if decoded.is_err() {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
let wc = decoded.unwrap();
let result: wchar_t = wc.chars().next().unwrap() as wchar_t;
if !pwc.is_null() {
*pwc = result;
}
return if result != 0 { size } else { 0 };
}
//It's guaranteed that we don't have any nullpointers here
pub unsafe fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize {
let dc = char::from_u32(wc as u32);
if dc.is_none() {
platform::errno = errno::EILSEQ;
return -1isize as usize;
}
let c = dc.unwrap();
let size = c.len_utf8();
let mut slice = slice::from_raw_parts_mut(s as *mut u8, size);
c.encode_utf8(slice);
size
}
+4
View File
@@ -54,6 +54,10 @@
/unistd/getopt
/unlink
/waitpid
/wchar/mbrtowc
/wchar/mbsrtowcs
/wchar/putwchar
/wchar/wcrtomb
/write
/time
/gmtime
+5 -1
View File
@@ -44,6 +44,10 @@ EXPECT_BINS=\
string/strtok_r \
unistd/getopt \
waitpid \
wchar/mbrtowc \
wchar/mbsrtowcs \
wchar/putwchar \
wchar/wcrtomb \
write \
time \
gmtime \
@@ -112,4 +116,4 @@ TAILLIBS=\
../target/openlibm/libopenlibm.a
%: %.c $(HEADLIBS) $(TAILLIBS)
gcc -fno-stack-protector -Wall $(CFLAGS) $(HEADLIBS) "$<" $(TAILLIBS) -o "$@"
gcc -fno-stack-protector -Wall -g $(CFLAGS) $(HEADLIBS) "$<" $(TAILLIBS) -o "$@"
View File
+2
View File
@@ -0,0 +1,2 @@
Processing 11 UTF-8 code units: [ 7a c3 9f e6 b0 b4 f0 9f 8d 8c 0 ]
into 5 wchar_t units: [ 7a df 6c34 1f34c 0 ]
+1
View File
@@ -0,0 +1 @@
The length, including '\0': 5
View File
+2
View File
@@ -0,0 +1,2 @@
Processing 5 wchar_t units: [ 7a df 6c34 1f34c 0 ]
into 11 UTF-8 code units: [ 7a c3 9f e6 b0 b4 f0 9f 8d 8c 0 ]
+30
View File
@@ -0,0 +1,30 @@
#include <stdio.h>
#include <string.h>
#include <wchar.h>
int main(void)
{
mbstate_t state;
memset(&state, 0, sizeof state);
char in[] = u8"z\u00df\u6c34\U0001F34C"; // or u8"zß水🍌"
size_t in_sz = sizeof in / sizeof *in;
printf("Processing %zu UTF-8 code units: [ ", in_sz); //Should be 11 regular chars
for(size_t n = 0; n < in_sz; ++n) printf("%#x ", (unsigned char)in[n]);
puts("]");
wchar_t out[in_sz];
char *p_in = in, *end = in + in_sz;
wchar_t *p_out = out;
int rc;
while((rc = mbrtowc(p_out, p_in, end - p_in, &state)) > 0)
{
p_in += rc;
p_out += 1;
}
size_t out_sz = p_out - out + 1;
printf("into %zu wchar_t units: [ ", out_sz); //Should be 5 wchars
for(size_t x = 0; x < out_sz; ++x) printf("%#x ", out[x]);
puts("]");
}
+23
View File
@@ -0,0 +1,23 @@
#include <stdio.h>
#include <wchar.h>
void print_as_wide(const char* mbstr)
{
mbstate_t state;
memset(&state, 0, sizeof state);
size_t len = 1 + mbsrtowcs(NULL, &mbstr, 0, &state);
wchar_t wstr[len];
mbsrtowcs(&wstr[0], &mbstr, len, &state);
//Should be 5
printf("The length, including '\\0': %i \n",len);
//missing wprintf to print this wide string
//wprintf(L"The wide string: %ls \n", &wstr[0]);
}
int main()
{
const char* mbstr = u8"z\u00df\u6c34\U0001f34c"; // or u8"zß水🍌"
print_as_wide(mbstr);
}
+21
View File
@@ -0,0 +1,21 @@
#include <string.h>
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
int main(void)
{
wchar_t *wcs = L"zß水🍌";
int i;
for (i = 0; wcs[i] != L'\0'; i++)
{
if (0xFFFFFFFFu == putwchar(wcs[i]))
{
printf("Unable to putwchar() the wide character.\n");
exit(EXIT_FAILURE);
}
}
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
#include <string.h>
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
int main( void )
{
mbstate_t state;
memset(&state, 0, sizeof state);
wchar_t in[] = L"zß水🍌"; // or "z\u00df\u6c34\U0001F34C"
size_t in_sz = sizeof in / sizeof *in;
printf("Processing %zu wchar_t units: [ ", in_sz);
for(size_t n = 0; n < in_sz; ++n) printf("%#x ", (unsigned int)in[n]);
puts("]");
char out[MB_CUR_MAX * in_sz];
char *p = out;
for(size_t n = 0; n < in_sz; ++n) {
int rc = wcrtomb(p, in[n], &state);
if(rc == -1) break;
p += rc;
}
size_t out_sz = p - out;
printf("into %zu UTF-8 code units: [ ", out_sz);
for(size_t x = 0; x < out_sz; ++x) printf("%#x ", +(unsigned char)out[x]);
puts("]");
}