wchar support
This commit is contained in:
Generated
+16
-2
@@ -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"
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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")))]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ cbindgen = { path = "../../cbindgen" }
|
||||
|
||||
[dependencies]
|
||||
platform = { path = "../platform" }
|
||||
stdlib = { path = "../stdlib" }
|
||||
ralloc = { path = "../../ralloc", default-features = false }
|
||||
errno = { path = "../errno" }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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!();
|
||||
}
|
||||
@@ -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"] }
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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
@@ -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 - 00–7F
|
||||
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 - C2–DF
|
||||
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 - E0–EF
|
||||
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 - F0–F4
|
||||
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!();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -54,6 +54,10 @@
|
||||
/unistd/getopt
|
||||
/unlink
|
||||
/waitpid
|
||||
/wchar/mbrtowc
|
||||
/wchar/mbsrtowcs
|
||||
/wchar/putwchar
|
||||
/wchar/wcrtomb
|
||||
/write
|
||||
/time
|
||||
/gmtime
|
||||
|
||||
+5
-1
@@ -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 "$@"
|
||||
|
||||
@@ -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 ]
|
||||
@@ -0,0 +1 @@
|
||||
The length, including '\0': 5
|
||||
@@ -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 ]
|
||||
@@ -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("]");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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("]");
|
||||
}
|
||||
Reference in New Issue
Block a user