diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 514666110e0fecb05f77933cbc827acebdb4c7d9..82380e3642866f98c3963067706a52ae8b114549 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -280,8 +280,15 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t { if amount == usize::MAX { return WEOF; } + + /* + We might have unget multiple bytes for a single wchar, eg, `ç` is [195, 167]. + We need to unget them in reversed, so they are pused as [..., 167, 195, ...] + When we do fgetwc, we pop from the Vec, getting the write order of bytes [195, 167]. + If we called ungetc in the non-reversed order, we would get [167, 195] + */ for i in 0..amount { - ungetc(bytes[i] as c_int, &mut *stream); + ungetc(bytes[amount - 1 - i] as c_int, &mut *stream); } wc diff --git a/tests/Makefile b/tests/Makefile index 47a54ada8fad63bdf5feedccf5f0711141070ab7..7bd1e8ac8c04fc7824a08987d925ae2404a0463f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -103,6 +103,7 @@ EXPECT_NAMES=\ unistd/swab \ unistd/write \ waitpid \ + wchar/fgetwc \ wchar/fwide \ wchar/mbrtowc \ wchar/mbsrtowcs \ diff --git a/tests/wchar/ungetwc.c b/tests/wchar/ungetwc.c index 015ba174e7de734e58d1760cb5b8b1fcdb9aae54..26f2649a4dd5c5d04337c632bede8c3b86dbc5ce 100644 --- a/tests/wchar/ungetwc.c +++ b/tests/wchar/ungetwc.c @@ -3,9 +3,11 @@ #include <stdio.h> #include <stdlib.h> #include <assert.h> - +#include <locale.h> + int main() { + setlocale(LC_ALL, ""); FILE *stream; wint_t wc; wint_t wc2; diff --git a/tests/wchar/ungetwc.in b/tests/wchar/ungetwc.in index 5e6162a56699d30c61e4e3a00bfe0754a012b024..a86807323c2d72f810b6c9ce673391c40d19cc9f 100644 --- a/tests/wchar/ungetwc.in +++ b/tests/wchar/ungetwc.in @@ -1 +1 @@ -123A \ No newline at end of file +123çA \ No newline at end of file