From 162999ac0baa7e9a2d8bdd762a470e00f339838d Mon Sep 17 00:00:00 2001 From: oddcoder Date: Sun, 26 Apr 2020 12:38:20 +0200 Subject: [PATCH 1/4] Move towlower and towupper to wctype.h and Implement it This patch creates wctype.h and impelementat two functions that belong to that header file towupper and towlower. These functions are building blocks for wcscasecmp and wcsncasecmp which are utilized by binutils. The implementation for towlower and towupper seams to be complex so this implementation is mimicking that of musl libc --- src/header/mod.rs | 1 + src/header/wchar/mod.rs | 19 +- src/header/wctype/casecmp.rs | 406 ++++++++++++++++++++++++++++++++ src/header/wctype/cbindgen.toml | 10 + src/header/wctype/mod.rs | 17 ++ 5 files changed, 438 insertions(+), 15 deletions(-) create mode 100644 src/header/wctype/casecmp.rs create mode 100644 src/header/wctype/cbindgen.toml create mode 100644 src/header/wctype/mod.rs diff --git a/src/header/mod.rs b/src/header/mod.rs index c6167c59bb..2de1178582 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -59,3 +59,4 @@ pub mod time; pub mod unistd; pub mod utime; pub mod wchar; +pub mod wctype; diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 8d63325f9c..ad371d8c68 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -3,14 +3,13 @@ use core::{char, ffi::VaList as va_list, mem, ptr, slice, usize}; use crate::{ - header::{ctype::isspace, errno::ERANGE, stdio::*, stdlib::MB_CUR_MAX, string, time::*}, + header::{ + ctype::isspace, errno::ERANGE, stdio::*, stdlib::MB_CUR_MAX, string, time::*, wctype::*, + }, platform::{self, types::*}, }; mod utf8; - -const WEOF: wint_t = 0xFFFF_FFFFu32; - #[repr(C)] #[derive(Clone, Copy)] pub struct mbstate_t; @@ -27,7 +26,7 @@ pub unsafe extern "C" fn btowc(c: c_int) -> wint_t { 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); + 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 WEOF; @@ -238,16 +237,6 @@ pub extern "C" fn swscanf(s: *const wchar_t, format: *const wchar_t, ap: va_list 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!(); diff --git a/src/header/wctype/casecmp.rs b/src/header/wctype/casecmp.rs new file mode 100644 index 0000000000..a15e9292f6 --- /dev/null +++ b/src/header/wctype/casecmp.rs @@ -0,0 +1,406 @@ +use crate::platform::types::*; +const tab: [c_uchar; 2666] = [ + 7, 8, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6, 14, 6, 6, 6, 6, 6, 6, 6, 6, 15, + 16, 17, 18, 6, 19, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 20, 21, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 22, 23, 6, 6, 6, 24, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 25, 6, 6, 6, 6, 26, 6, 6, 6, 6, 6, 6, 6, 27, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 28, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 29, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 30, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 43, 43, 43, + 43, 43, 43, 43, 43, 1, 0, 84, 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 7, 43, 43, 91, 86, 86, 86, 86, + 86, 86, 86, 74, 86, 86, 5, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 36, + 80, 121, 49, 80, 49, 80, 49, 56, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, + 78, 49, 2, 78, 13, 13, 78, 3, 78, 0, 36, 110, 0, 78, 49, 38, 110, 81, 78, 36, 80, 78, 57, 20, + 129, 27, 29, 29, 83, 49, 80, 49, 80, 13, 49, 80, 49, 80, 49, 80, 27, 83, 36, 80, 49, 2, 92, + 123, 92, 123, 92, 123, 92, 123, 92, 123, 20, 121, 92, 123, 92, 123, 92, 45, 43, 73, 3, 72, 3, + 120, 92, 123, 20, 0, 150, 10, 1, 43, 40, 6, 6, 0, 42, 6, 42, 42, 43, 7, 187, 181, 43, 30, 0, + 43, 7, 43, 43, 43, 1, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 1, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 205, 70, 205, 43, 0, 37, 43, 7, 1, 6, 1, 85, 86, 86, 86, 86, 86, 85, 86, 86, 2, + 36, 129, 129, 129, 129, 129, 21, 129, 129, 129, 0, 0, 43, 0, 178, 209, 178, 209, 178, 209, 178, + 209, 0, 0, 205, 204, 1, 0, 215, 215, 215, 215, 215, 131, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 28, 0, 0, 0, 0, 0, 49, 80, 49, + 80, 49, 80, 49, 80, 49, 80, 49, 2, 0, 0, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, + 80, 49, 80, 49, 80, 78, 49, 80, 49, 80, 78, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, + 80, 49, 2, 135, 166, 135, 166, 135, 166, 135, 166, 135, 166, 135, 166, 135, 166, 135, 166, 42, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 84, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 12, 0, 12, 42, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 42, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 86, 86, 108, 129, 21, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 7, 108, 3, 65, 43, 43, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 44, 86, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 108, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 37, 6, + 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, + 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 86, 122, 158, 38, 6, 37, + 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, + 37, 6, 1, 43, 43, 79, 86, 86, 44, 43, 127, 86, 86, 57, 43, 43, 85, 86, 86, 43, 43, 79, 86, 86, + 44, 43, 127, 86, 86, 129, 55, 117, 91, 123, 92, 43, 43, 79, 86, 86, 2, 172, 4, 0, 0, 57, 43, + 43, 85, 86, 86, 43, 43, 79, 86, 86, 44, 43, 43, 86, 86, 50, 19, 129, 87, 0, 111, 129, 126, 201, + 215, 126, 45, 129, 129, 14, 126, 57, 127, 111, 87, 0, 129, 129, 126, 21, 0, 126, 3, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 43, 36, 43, 151, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, + 43, 43, 43, 43, 43, 86, 86, 86, 86, 86, 128, 129, 129, 129, 129, 57, 187, 42, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 1, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 201, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 208, 13, 0, 78, 49, 2, 180, 193, 193, 215, 215, 36, 80, 49, 80, 49, 80, 49, 80, + 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, + 49, 80, 215, 215, 83, 193, 71, 212, 215, 215, 215, 5, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 7, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 78, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 13, 0, 0, 0, 0, 0, 36, 80, + 49, 80, 49, 80, 49, 80, 49, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 121, 92, + 123, 92, 123, 79, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, + 92, 123, 92, 45, 43, 43, 121, 20, 92, 123, 92, 45, 121, 42, 92, 39, 92, 123, 92, 123, 92, 123, + 164, 0, 10, 180, 92, 123, 92, 123, 79, 3, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 7, + 0, 72, 86, 86, 86, 86, 86, 86, 86, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 85, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 0, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 85, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +]; +const rules: [c_int; 240] = [ + 0x0, 0x2001, -0x2000, 0x1dbf00, 0x2e700, 0x7900, 0x2402, 0x101, -0x100, 0x0, 0x201, -0x200, + -0xc6ff, -0xe800, -0x78ff, -0x12c00, 0xc300, 0xd201, 0xce01, 0xcd01, 0x4f01, 0xca01, 0xcb01, + 0xcf01, 0x6100, 0xd301, 0xd101, 0xa300, 0xd501, 0x8200, 0xd601, 0xda01, 0xd901, 0xdb01, 0x3800, + 0x3, -0x4f00, -0x60ff, -0x37ff, 0x242802, 0x0, 0x101, -0x100, -0xcd00, -0xda00, -0x81ff, + 0x2a2b01, -0xa2ff, 0x2a2801, 0x2a3f00, -0xc2ff, 0x4501, 0x4701, 0x2a1f00, 0x2a1c00, 0x2a1e00, + -0xd200, -0xce00, -0xca00, -0xcb00, 0xa54f00, 0xa54b00, -0xcf00, 0xa52800, 0xa54400, -0xd100, + -0xd300, 0x29f700, 0xa54100, 0x29fd00, -0xd500, -0xd600, 0x29e700, 0xa54300, 0xa52a00, -0x4500, + -0xd900, -0x4700, -0xdb00, 0xa51500, 0xa51200, 0x4c2402, 0x0, 0x2001, -0x2000, 0x101, -0x100, + 0x5400, 0x7401, 0x2601, 0x2501, 0x4001, 0x3f01, -0x2600, -0x2500, -0x1f00, -0x4000, -0x3f00, + 0x801, -0x3e00, -0x3900, -0x2f00, -0x3600, -0x800, -0x5600, -0x5000, 0x700, -0x7400, -0x3bff, + -0x6000, -0x6ff, 0x701a02, 0x101, -0x100, 0x2001, -0x2000, 0x5001, 0xf01, -0xf00, 0x0, 0x3001, + -0x3000, 0x101, -0x100, 0x0, 0xbc000, 0x1c6001, 0x0, 0x97d001, 0x801, -0x800, 0x8a0502, 0x0, + -0xbbfff, -0x186200, 0x89c200, -0x182500, -0x186e00, -0x186d00, -0x186400, -0x186300, + -0x185c00, 0x0, 0x8a3800, 0x8a0400, 0xee600, 0x101, -0x100, 0x0, -0x3b00, -0x1dbeff, 0x8f1d02, + 0x800, -0x7ff, 0x0, 0x5600, -0x55ff, 0x4a00, 0x6400, 0x8000, 0x7000, 0x7e00, 0x900, -0x49ff, + -0x8ff, -0x1c2500, -0x63ff, -0x6fff, -0x7fff, -0x7dff, 0xac0502, 0x0, 0x1001, -0x1000, 0x1c01, + 0x101, -0x1d5cff, -0x20beff, -0x2045ff, -0x1c00, 0xb10b02, 0x101, -0x100, 0x3001, -0x3000, 0x0, + -0x29f6ff, -0xee5ff, -0x29e6ff, -0x2a2b00, -0x2a2800, -0x2a1bff, -0x29fcff, -0x2a1eff, + -0x2a1dff, -0x2a3eff, 0x0, -0x1c6000, 0x0, 0x101, -0x100, 0xbc0c02, 0x0, 0x101, -0x100, + -0xa543ff, 0x3a001, -0x8a03ff, -0xa527ff, 0x3000, -0xa54eff, -0xa54aff, -0xa540ff, -0xa511ff, + -0xa529ff, -0xa514ff, -0x2fff, -0xa542ff, -0x8a37ff, 0x0, -0x97d000, -0x3a000, 0x0, 0x2001, + -0x2000, 0x0, 0x2801, -0x2800, 0x0, 0x4001, -0x4000, 0x0, 0x2001, -0x2000, 0x0, 0x2001, + -0x2000, 0x0, 0x2201, -0x2200, +]; +const rulebases: [c_uchar; 512] = [ + 0, 6, 39, 81, 111, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 142, 146, 151, 0, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 201, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +]; +const exceptions: [[c_uchar; 2]; 200] = [ + [48, 12], + [49, 13], + [120, 14], + [127, 15], + [128, 16], + [129, 17], + [134, 18], + [137, 19], + [138, 19], + [142, 20], + [143, 21], + [144, 22], + [147, 19], + [148, 23], + [149, 24], + [150, 25], + [151, 26], + [154, 27], + [156, 25], + [157, 28], + [158, 29], + [159, 30], + [166, 31], + [169, 31], + [174, 31], + [177, 32], + [178, 32], + [183, 33], + [191, 34], + [197, 35], + [200, 35], + [203, 35], + [221, 36], + [242, 35], + [246, 37], + [247, 38], + [32, 45], + [58, 46], + [61, 47], + [62, 48], + [63, 49], + [64, 49], + [67, 50], + [68, 51], + [69, 52], + [80, 53], + [81, 54], + [82, 55], + [83, 56], + [84, 57], + [89, 58], + [91, 59], + [92, 60], + [97, 61], + [99, 62], + [101, 63], + [102, 64], + [104, 65], + [105, 66], + [106, 64], + [107, 67], + [108, 68], + [111, 66], + [113, 69], + [114, 70], + [117, 71], + [125, 72], + [130, 73], + [135, 74], + [137, 75], + [138, 76], + [139, 76], + [140, 77], + [146, 78], + [157, 79], + [158, 80], + [69, 87], + [123, 29], + [124, 29], + [125, 29], + [127, 88], + [134, 89], + [136, 90], + [137, 90], + [138, 90], + [140, 91], + [142, 92], + [143, 92], + [172, 93], + [173, 94], + [174, 94], + [175, 94], + [194, 95], + [204, 96], + [205, 97], + [206, 97], + [207, 98], + [208, 99], + [209, 100], + [213, 101], + [214, 102], + [215, 103], + [240, 104], + [241, 105], + [242, 106], + [243, 107], + [244, 108], + [245, 109], + [249, 110], + [253, 45], + [254, 45], + [255, 45], + [80, 105], + [81, 105], + [82, 105], + [83, 105], + [84, 105], + [85, 105], + [86, 105], + [87, 105], + [88, 105], + [89, 105], + [90, 105], + [91, 105], + [92, 105], + [93, 105], + [94, 105], + [95, 105], + [130, 0], + [131, 0], + [132, 0], + [133, 0], + [134, 0], + [135, 0], + [136, 0], + [137, 0], + [192, 117], + [207, 118], + [128, 137], + [129, 138], + [130, 139], + [133, 140], + [134, 141], + [112, 157], + [113, 157], + [118, 158], + [119, 158], + [120, 159], + [121, 159], + [122, 160], + [123, 160], + [124, 161], + [125, 161], + [179, 162], + [186, 163], + [187, 163], + [188, 164], + [190, 165], + [195, 162], + [204, 164], + [218, 166], + [219, 166], + [229, 106], + [234, 167], + [235, 167], + [236, 110], + [243, 162], + [248, 168], + [249, 168], + [250, 169], + [251, 169], + [252, 164], + [38, 176], + [42, 177], + [43, 178], + [78, 179], + [132, 8], + [98, 186], + [99, 187], + [100, 188], + [101, 189], + [102, 190], + [109, 191], + [110, 192], + [111, 193], + [112, 194], + [126, 195], + [127, 195], + [125, 207], + [141, 208], + [148, 209], + [171, 210], + [172, 211], + [173, 212], + [176, 213], + [177, 214], + [178, 215], + [196, 216], + [197, 217], + [198, 218], +]; + +pub fn casemap(mut c: u32, dir: i32) -> wint_t { + if c >= 0x20000 { + return c; + } + let c0 = c; + let b = c >> 8; + c &= 255; + let x = c / 3; + let y = c % 3; + /* lookup entry in two-level base-6 table */ + let mut v: c_uint = tab[(tab[b as usize] as u32 * 86 + x) as usize] as c_uint; + let mt: [c_uint; 3] = [2048, 342, 57]; + v = (v * mt[y as usize] >> 11) % 6; + + /* use the bit vector out of the tables as an index into + * a block-specific set of rules and decode the rule into + * a type and a case-mapping delta. */ + let mut r: c_int = rules[(rulebases[b as usize] as c_uint + v) as usize]; + let mut rt: c_uint = (r & 255) as c_uint; + let mut rd: c_int = r >> 8; + + /* rules 0/1 are simple lower/upper case with a delta. + * apply according to desired mapping direction. */ + if rt < 2 { + let tmp = -((rt ^ dir as c_uint) as c_int) as c_uint; + return c0.wrapping_add(rd as c_uint & tmp); + } + + /* binary search. endpoints of the binary search for + * this block are stored in the rule delta field. */ + let mut xn: c_uint = (rd & 0xff) as c_uint; + let mut xb: c_uint = rd as c_uint >> 8; + while xn != 0 { + let attempt: c_uint = exceptions[(xb + xn / 2) as usize][0] as c_uint; + if attempt == c { + r = rules[exceptions[(xb + xn / 2) as usize][1] as usize]; + rt = r as c_uint & 255; + rd = r >> 8; + if rt < 2 { + let tmp = -((rt ^ dir as c_uint) as c_int) as c_uint; + return c0.wrapping_add(rd as c_uint & tmp); + } + /* Hard-coded for the four exceptional titlecase */ + if dir == 0 { + return c0 + 1; + } else { + return c0 - 1; + } + } else if attempt > c { + xn /= 2; + } else { + xb += xn / 2; + xn -= xn / 2; + } + } + return c0; +} diff --git a/src/header/wctype/cbindgen.toml b/src/header/wctype/cbindgen.toml new file mode 100644 index 0000000000..3f2c4ff4db --- /dev/null +++ b/src/header/wctype/cbindgen.toml @@ -0,0 +1,10 @@ +sys_includes = ["stddef.h", "stdint.h", "time.h", "stdio.h" ] +include_guard = "_WCTYPE_H" +header = "" +language = "C" +style = "Type" +no_includes = true +cpp_compat = true + +[enum] +prefix_with_name = true diff --git a/src/header/wctype/mod.rs b/src/header/wctype/mod.rs new file mode 100644 index 0000000000..b4b7b0eaa9 --- /dev/null +++ b/src/header/wctype/mod.rs @@ -0,0 +1,17 @@ +//! wchar implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/wchar.h.html + +use crate::platform::types::*; + +mod casecmp; +use casecmp::casemap; +pub const WEOF: wint_t = 0xFFFF_FFFFu32; + +#[no_mangle] +pub extern "C" fn towlower(wc: wint_t) -> wint_t { + casemap(wc, 0) +} + +#[no_mangle] +pub extern "C" fn towupper(wc: wint_t) -> wint_t { + casemap(wc, 1) +} From 9725d3418af87be960cba46f1c957b24e9d69550 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Sun, 26 Apr 2020 12:33:51 +0200 Subject: [PATCH 2/4] Test towlower and towupper --- tests/Makefile | 4 +++- tests/expected/wctype/towlower.stderr | 0 tests/expected/wctype/towlower.stdout | 2 ++ tests/expected/wctype/towupper.stderr | 0 tests/expected/wctype/towupper.stdout | 2 ++ tests/wctype/towlower.c | 12 ++++++++++++ tests/wctype/towupper.c | 12 ++++++++++++ 7 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/expected/wctype/towlower.stderr create mode 100644 tests/expected/wctype/towlower.stdout create mode 100644 tests/expected/wctype/towupper.stderr create mode 100644 tests/expected/wctype/towupper.stdout create mode 100644 tests/wctype/towlower.c create mode 100644 tests/wctype/towupper.c diff --git a/tests/Makefile b/tests/Makefile index 716600fa7a..6b056b4dc1 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -103,7 +103,9 @@ EXPECT_NAMES=\ wchar/wcsstr \ wchar/wcstod \ wchar/wcstok \ - wchar/wcstol + wchar/wcstol \ + wctype/towlower \ + wctype/towupper # TODO: Fix these # mkfifo diff --git a/tests/expected/wctype/towlower.stderr b/tests/expected/wctype/towlower.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/wctype/towlower.stdout b/tests/expected/wctype/towlower.stdout new file mode 100644 index 0000000000..fdbf17836f --- /dev/null +++ b/tests/expected/wctype/towlower.stdout @@ -0,0 +1,2 @@ +HaLf WiDe ChAr StRiNg! +half wide char string! diff --git a/tests/expected/wctype/towupper.stderr b/tests/expected/wctype/towupper.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/wctype/towupper.stdout b/tests/expected/wctype/towupper.stdout new file mode 100644 index 0000000000..a09771e7bc --- /dev/null +++ b/tests/expected/wctype/towupper.stdout @@ -0,0 +1,2 @@ +HaLf WiDe ChAr StRiNg! +HALF WIDE CHAR STRING! diff --git a/tests/wctype/towlower.c b/tests/wctype/towlower.c new file mode 100644 index 0000000000..a99d4252bd --- /dev/null +++ b/tests/wctype/towlower.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int main() { + wchar_t *str = L"HaLf WiDe ChAr StRiNg!\n"; + fputws(str, stdout); + for (int i = 0; i < wcslen(str); i++) { + putwchar(towlower(str[i])); + } + return 0; +} \ No newline at end of file diff --git a/tests/wctype/towupper.c b/tests/wctype/towupper.c new file mode 100644 index 0000000000..61fb09edf4 --- /dev/null +++ b/tests/wctype/towupper.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int main() { + wchar_t *str = L"HaLf WiDe ChAr StRiNg!\n"; + fputws(str, stdout); + for (int i = 0; i < wcslen(str); i++) { + putwchar(towupper(str[i])); + } + return 0; +} \ No newline at end of file From eac69c920d53b55880c7de3ad0bd6f1644585b1e Mon Sep 17 00:00:00 2001 From: oddcoder Date: Sun, 26 Apr 2020 12:39:18 +0200 Subject: [PATCH 3/4] Implement wcscasecmp and wcsncasecmp This patch implements wcscasecmp and wcsncasecmp. These two function are required for binutils to link against relibc. --- src/header/wchar/mod.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index ad371d8c68..4c4a281bbd 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -726,3 +726,35 @@ pub extern "C" fn wprintf(format: *const wchar_t, ap: va_list) -> c_int { pub extern "C" fn wscanf(format: *const wchar_t, ap: va_list) -> c_int { unimplemented!(); } + +#[no_mangle] +pub extern "C" fn wcscasecmp(mut s1: *const wchar_t, mut s2: *const wchar_t) -> c_int { + unsafe { + while *s1 != 0 && *s2 != 0 { + if towlower(*s1 as wint_t) != towlower(*s2 as wint_t) { + break; + } + s1 = s1.add(1); + s2 = s2.add(1); + } + let result = towlower(*s1 as wint_t).wrapping_sub(towlower(*s2 as wint_t)); + return result as c_int; + } +} + +#[no_mangle] +pub extern "C" fn wcsncasecmp(mut s1: *const wchar_t, mut s2: *const wchar_t, n: size_t) -> c_int { + if n == 0 { + return 0; + } + unsafe { + for _ in 0..n { + if *s1 == 0 || *s2 == 0 || towlower(*s1 as wint_t) != towlower(*s2 as wint_t) { + return towlower(*s1 as wint_t).wrapping_sub(towlower(*s2 as wint_t)) as c_int; + } + s1 = s1.add(1); + s2 = s2.add(1); + } + return 0; + } +} From e9615065acd86735758c579a892c070d8186bc90 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Sun, 26 Apr 2020 19:05:50 +0200 Subject: [PATCH 4/4] Add tests for both wcsncasecmp and wcscasecmp --- tests/Makefile | 2 ++ tests/expected/wchar/wcscasecmp.stderr | 0 tests/expected/wchar/wcscasecmp.stdout | 4 ++++ tests/expected/wchar/wcsncasecmp.stderr | 0 tests/expected/wchar/wcsncasecmp.stdout | 5 +++++ tests/wchar/wcscasecmp.c | 11 +++++++++++ tests/wchar/wcsncasecmp.c | 12 ++++++++++++ 7 files changed, 34 insertions(+) create mode 100644 tests/expected/wchar/wcscasecmp.stderr create mode 100644 tests/expected/wchar/wcscasecmp.stdout create mode 100644 tests/expected/wchar/wcsncasecmp.stderr create mode 100644 tests/expected/wchar/wcsncasecmp.stdout create mode 100644 tests/wchar/wcscasecmp.c create mode 100644 tests/wchar/wcsncasecmp.c diff --git a/tests/Makefile b/tests/Makefile index 6b056b4dc1..eec484b078 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -104,6 +104,8 @@ EXPECT_NAMES=\ wchar/wcstod \ wchar/wcstok \ wchar/wcstol \ + wchar/wcscasecmp \ + wchar/wcsncasecmp \ wctype/towlower \ wctype/towupper # TODO: Fix these diff --git a/tests/expected/wchar/wcscasecmp.stderr b/tests/expected/wchar/wcscasecmp.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/wchar/wcscasecmp.stdout b/tests/expected/wchar/wcscasecmp.stdout new file mode 100644 index 0000000000..fdd11f6552 --- /dev/null +++ b/tests/expected/wchar/wcscasecmp.stdout @@ -0,0 +1,4 @@ +wcscasecmp(s1, s1) = 0 +wcscasecmp(s1, s2) = -1 +wcscasecmp(s2, s1) = 1 +wcscasecmp(s2, s2) = 0 diff --git a/tests/expected/wchar/wcsncasecmp.stderr b/tests/expected/wchar/wcsncasecmp.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/wchar/wcsncasecmp.stdout b/tests/expected/wchar/wcsncasecmp.stdout new file mode 100644 index 0000000000..6a4bd43fc4 --- /dev/null +++ b/tests/expected/wchar/wcsncasecmp.stdout @@ -0,0 +1,5 @@ +wcsncasecmp(s1, s1, 17) = 0 +wcsncasecmp(s1, s2, 17) = -1 +wcsncasecmp(s2, s1, 17) = 1 +wcsncasecmp(s2, s1, 15) = 0 +wcsncasecmp(s1, s2, 0) = 0 diff --git a/tests/wchar/wcscasecmp.c b/tests/wchar/wcscasecmp.c new file mode 100644 index 0000000000..7241be198a --- /dev/null +++ b/tests/wchar/wcscasecmp.c @@ -0,0 +1,11 @@ +#include +#include + +int main() { + wchar_t *s1 = L"ThIs Is StRiNg 1."; + wchar_t *s2 = L"tHiS iS sTrInG 2."; + printf("wcscasecmp(s1, s1) = %d\n", wcscasecmp(s1, s1)); + printf("wcscasecmp(s1, s2) = %d\n", wcscasecmp(s1, s2)); + printf("wcscasecmp(s2, s1) = %d\n", wcscasecmp(s2, s1)); + printf("wcscasecmp(s2, s2) = %d\n", wcscasecmp(s2, s2)); +} diff --git a/tests/wchar/wcsncasecmp.c b/tests/wchar/wcsncasecmp.c new file mode 100644 index 0000000000..d0e815fe6e --- /dev/null +++ b/tests/wchar/wcsncasecmp.c @@ -0,0 +1,12 @@ +#include +#include + +int main() { + wchar_t *s1 = L"This is string 1."; + wchar_t *s2 = L"This is string 2."; + printf("wcsncasecmp(s1, s1, 17) = %d\n", wcsncasecmp(s1, s1, 17)); + printf("wcsncasecmp(s1, s2, 17) = %d\n", wcsncasecmp(s1, s2, 17)); + printf("wcsncasecmp(s2, s1, 17) = %d\n", wcsncasecmp(s2, s1, 17)); + printf("wcsncasecmp(s2, s1, 15) = %d\n", wcsncasecmp(s2, s1, 15)); + printf("wcsncasecmp(s1, s2, 0) = %d\n", wcsncasecmp(s1, s2, 0)); +}