diff --git a/src/header/wctype/mod.rs b/src/header/wctype/mod.rs
index 005bca0447da9d68b96109003fc7fe435f4e17ff..d0fc6dd5b0a04e9edef69b1f92535c2d26da7698 100644
--- a/src/header/wctype/mod.rs
+++ b/src/header/wctype/mod.rs
@@ -8,6 +8,7 @@ mod casecmp;
 mod punct;
 
 pub type wctype_t = u32;
+pub type wctrans_t = *const i32;
 
 pub const WEOF: wint_t = 0xFFFF_FFFFu32;
 
@@ -24,6 +25,9 @@ pub const WCTYPE_SPACE: wctype_t = 10;
 pub const WCTYPE_UPPER: wctype_t = 11;
 pub const WCTYPE_XDIGIT: wctype_t = 12;
 
+const WCTRANSUP: wctrans_t = 1 as wctrans_t;
+const WCTRANSLW: wctrans_t = 2 as wctrans_t;
+
 #[no_mangle]
 pub extern "C" fn iswctype(wc: wint_t, desc: wctype_t) -> c_int {
     match desc {
@@ -173,3 +177,22 @@ pub extern "C" fn towlower(wc: wint_t) -> wint_t {
 pub extern "C" fn towupper(wc: wint_t) -> wint_t {
     casemap(wc, 1)
 }
+
+#[no_mangle]
+pub extern "C" fn wctrans(class: *const c_char) -> wctrans_t {
+    let class_cstr = unsafe { CStr::from_ptr(class) };
+    match class_cstr.to_bytes() {
+        b"toupper" => WCTRANSUP,
+        b"tolower" => WCTRANSLW,
+        _ => 0 as wctrans_t,
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn towctrans(wc: wint_t, trans: wctrans_t) -> wint_t {
+    match trans {
+        WCTRANSUP => towupper(wc),
+        WCTRANSLW => towlower(wc),
+        _ => wc,
+    }
+}
diff --git a/tests/wctype/towlower.c b/tests/wctype/towlower.c
index a99d4252bd56696a045358f93ab5696ccd897e7f..fe92d71c963fc30bc9eb5bd5d6fb8ce49a662b11 100644
--- a/tests/wctype/towlower.c
+++ b/tests/wctype/towlower.c
@@ -6,7 +6,7 @@ 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]));
+        putwchar(towctrans(str[i], wctrans("tolower")));
     }
     return 0;
-}
\ No newline at end of file
+}
diff --git a/tests/wctype/towupper.c b/tests/wctype/towupper.c
index 61fb09edf4f2e458dfdea505a269688e71d43eae..72404edd7d59ce059443d72f2f6fdcff8f23d236 100644
--- a/tests/wctype/towupper.c
+++ b/tests/wctype/towupper.c
@@ -6,7 +6,7 @@ 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]));
+        putwchar(towctrans(str[i], wctrans("toupper")));
     }
     return 0;
-}
\ No newline at end of file
+}