relibc/header/wctype/
mod.rs1use self::casecmp::casemap;
8use crate::{
9 c_str::CStr,
10 header::ctype,
11 platform::types::{c_char, c_int, wint_t},
12};
13
14mod alpha;
15mod casecmp;
16mod punct;
17
18pub type wctype_t = u32;
19pub type wctrans_t = *const i32;
20
21pub const WEOF: wint_t = 0xFFFF_FFFFu32;
22
23pub const WCTYPE_ALNUM: wctype_t = 1;
24pub const WCTYPE_ALPHA: wctype_t = 2;
25pub const WCTYPE_BLANK: wctype_t = 3;
26pub const WCTYPE_CNTRL: wctype_t = 4;
27pub const WCTYPE_DIGIT: wctype_t = 5;
28pub const WCTYPE_GRAPH: wctype_t = 6;
29pub const WCTYPE_LOWER: wctype_t = 7;
30pub const WCTYPE_PRINT: wctype_t = 8;
31pub const WCTYPE_PUNCT: wctype_t = 9;
32pub const WCTYPE_SPACE: wctype_t = 10;
33pub const WCTYPE_UPPER: wctype_t = 11;
34pub const WCTYPE_XDIGIT: wctype_t = 12;
35
36const WCTRANSUP: wctrans_t = 1 as wctrans_t;
37const WCTRANSLW: wctrans_t = 2 as wctrans_t;
38
39#[unsafe(no_mangle)]
41pub extern "C" fn iswalnum(wc: wint_t) -> c_int {
42 c_int::from(iswdigit(wc) != 0 || iswalpha(wc) != 0)
43}
44
45#[unsafe(no_mangle)]
47pub extern "C" fn iswalpha(wc: wint_t) -> c_int {
48 c_int::from(alpha::is(wc as usize))
49}
50
51#[unsafe(no_mangle)]
53pub extern "C" fn iswblank(wc: wint_t) -> c_int {
54 ctype::isblank(wc as c_int)
55}
56
57#[unsafe(no_mangle)]
59pub extern "C" fn iswcntrl(wc: wint_t) -> c_int {
60 c_int::from(
61 wc < 32
62 || wc.wrapping_sub(0x7f) < 33
63 || wc.wrapping_sub(0x2028) < 2
64 || wc.wrapping_sub(0xfff9) < 3,
65 )
66}
67
68#[unsafe(no_mangle)]
70pub extern "C" fn iswctype(wc: wint_t, desc: wctype_t) -> c_int {
71 match desc {
72 WCTYPE_ALNUM => iswalnum(wc),
73 WCTYPE_ALPHA => iswalpha(wc),
74 WCTYPE_BLANK => iswblank(wc),
75 WCTYPE_CNTRL => iswcntrl(wc),
76 WCTYPE_DIGIT => iswdigit(wc),
77 WCTYPE_GRAPH => iswgraph(wc),
78 WCTYPE_LOWER => iswlower(wc),
79 WCTYPE_PRINT => iswprint(wc),
80 WCTYPE_PUNCT => iswpunct(wc),
81 WCTYPE_SPACE => iswspace(wc),
82 WCTYPE_UPPER => iswupper(wc),
83 WCTYPE_XDIGIT => iswxdigit(wc),
84 _ => 0,
85 }
86}
87
88#[unsafe(no_mangle)]
90pub extern "C" fn iswdigit(wc: wint_t) -> c_int {
91 c_int::from(wc.wrapping_sub('0' as wint_t) < 10)
92}
93
94#[unsafe(no_mangle)]
96pub extern "C" fn iswgraph(wc: wint_t) -> c_int {
97 c_int::from(iswspace(wc) == 0 && iswprint(wc) != 0)
98}
99
100#[unsafe(no_mangle)]
102pub extern "C" fn iswlower(wc: wint_t) -> c_int {
103 c_int::from(towupper(wc) != wc)
104}
105
106#[unsafe(no_mangle)]
108pub extern "C" fn iswprint(wc: wint_t) -> c_int {
109 if wc < 0xff {
110 c_int::from(((wc + 1) & 0x7f) >= 0x21)
111 } else if wc < 0x2028
112 || wc.wrapping_sub(0x202a) < 0xd800 - 0x202a
113 || wc.wrapping_sub(0xe000) < 0xfff9 - 0xe000
114 {
115 1
116 } else if wc.wrapping_sub(0xfffc) > 0x10ffff - 0xfffc || (wc & 0xfffe) == 0xfffe {
117 0
118 } else {
119 1
120 }
121}
122
123#[unsafe(no_mangle)]
125pub extern "C" fn iswpunct(wc: wint_t) -> c_int {
126 c_int::from(punct::is(wc as usize))
127}
128
129#[unsafe(no_mangle)]
131pub extern "C" fn iswspace(wc: wint_t) -> c_int {
132 c_int::from(
133 [
134 ' ' as wint_t,
135 '\t' as wint_t,
136 '\n' as wint_t,
137 '\r' as wint_t,
138 11,
139 12,
140 0x0085,
141 0x2000,
142 0x2001,
143 0x2002,
144 0x2003,
145 0x2004,
146 0x2005,
147 0x2006,
148 0x2008,
149 0x2009,
150 0x200a,
151 0x2028,
152 0x2029,
153 0x205f,
154 0x3000,
155 ]
156 .contains(&wc),
157 )
158}
159
160#[unsafe(no_mangle)]
162pub extern "C" fn iswupper(wc: wint_t) -> c_int {
163 c_int::from(towlower(wc) != wc)
164}
165
166#[unsafe(no_mangle)]
168pub extern "C" fn iswxdigit(wc: wint_t) -> c_int {
169 c_int::from(wc.wrapping_sub('0' as wint_t) < 10 || (wc | 32).wrapping_sub('a' as wint_t) < 6)
170}
171
172#[unsafe(no_mangle)]
174pub extern "C" fn towctrans(wc: wint_t, trans: wctrans_t) -> wint_t {
175 match trans {
176 WCTRANSUP => towupper(wc),
177 WCTRANSLW => towlower(wc),
178 _ => wc,
179 }
180}
181
182#[unsafe(no_mangle)]
184pub extern "C" fn towlower(wc: wint_t) -> wint_t {
185 casemap(wc, 0)
186}
187
188#[unsafe(no_mangle)]
190pub extern "C" fn towupper(wc: wint_t) -> wint_t {
191 casemap(wc, 1)
192}
193
194#[unsafe(no_mangle)]
200pub unsafe extern "C" fn wctrans(class: *const c_char) -> wctrans_t {
201 let class_cstr = unsafe { CStr::from_ptr(class) };
202 match class_cstr.to_bytes() {
203 b"toupper" => WCTRANSUP,
204 b"tolower" => WCTRANSLW,
205 _ => 0 as wctrans_t,
206 }
207}
208
209#[unsafe(no_mangle)]
215pub unsafe extern "C" fn wctype(name: *const c_char) -> wctype_t {
216 let name_cstr = unsafe { CStr::from_ptr(name) };
217 match name_cstr.to_bytes() {
218 b"alnum" => WCTYPE_ALNUM,
219 b"alpha" => WCTYPE_ALPHA,
220 b"blank" => WCTYPE_BLANK,
221 b"cntrl" => WCTYPE_CNTRL,
222 b"digit" => WCTYPE_DIGIT,
223 b"graph" => WCTYPE_GRAPH,
224 b"lower" => WCTYPE_LOWER,
225 b"print" => WCTYPE_PRINT,
226 b"punct" => WCTYPE_PUNCT,
227 b"space" => WCTYPE_SPACE,
228 b"upper" => WCTYPE_UPPER,
229 b"xdigit" => WCTYPE_XDIGIT,
230 _ => 0,
231 }
232}