/* Author: Ruud Harmsen, August 2021. Explanation: https://rudhar.com/sfreview/siworin/siworin14.htm See also: https://rudhar.com/sfreview/siworin/siworin15.htm Meant to illustrate this bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28258 */ #include #include #include #include #include #include #include #define REPERR(LINE, ERRNO) { \ fprintf(stderr, "Line %3d, error %d ", (LINE), (ERRNO)); \ perror(NULL);} char bytes[] = u8"Há, ναι, არა\n"; wchar_t chars[sizeof bytes * sizeof (wchar_t)]; int main (void) { FILE *fpc, *fpw; int i; int c = 0; wint_t cw = 0; int retval; if (!setlocale(LC_ALL, "en_US.UTF-8")) REPERR(__LINE__, errno); for (i = 0; i < sizeof bytes && bytes[i]; i++) { retval = mbtowc(&cw, bytes + i, 8); fprintf(stderr, "retval = %2d, cw = \'%lc\'\n", retval, iswprint(cw) ? cw : L'?'); retval = mbstowcs(chars, bytes + i, 64); fprintf(stderr, "retval = %2d, chars = %ls", retval, chars); } /* Write a test file to disk. */ fpc = fopen("in", "w"); fwrite(bytes, 1, sizeof bytes - 1, fpc); fclose(fpc); /* Open two streams for the same file, one in character mode, one in wide mode. */ fpc = fopen("in", "r"); fpw = fopen("in", "r"); fprintf(stderr, "\n"); for (i = 0; i < sizeof bytes && bytes[i]; i++) { if ((retval = fseek(fpc, i, SEEK_SET)) < 0) {fprintf(stderr, "Tried to fseek to byte %d\n", i); REPERR(__LINE__, errno);} if ((retval = fseek(fpw, i, SEEK_SET)) < 0) {fprintf(stderr, "Tried to fseek to byte %d\n", i); REPERR(__LINE__, errno);} c = fgetc(fpc); if (ferror(fpc)) {REPERR(__LINE__, errno); clearerr(fpc);} cw = fgetwc(fpw); if (ferror(fpw)) {REPERR(__LINE__, errno); clearerr(fpw);} if (feof(fpc) || feof(fpw)) break; fprintf(stderr, "Pos %2d, char %02x-%c, wide char %08x-%lc\n", i, c , isprint (c) ? c : '?', cw, iswprint(cw) ? cw : L'?'); } fclose(fpc); fclose(fpw); return 0; }