/* Illustration of strcoll and wcscoll dissagreement in the as_SA.UTF-8 and th_TH.UTF-8 locales. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include static const wchar_t line1[] = L"\x0020\x0020\x03A3\x1F72\x0020\x03B3\x03BD\x03C9\x03C1\x1F77\x03B6\x03C9\x0020\x1F00\x03C0\x1F78\x0020\x03C4\x1F74\x03BD\x0020\x03BA\x1F79\x03C8\x03B7\x000A"; static const wchar_t line2[] = L"\x0020\x0020\x1225\x122B\x0020\x12A8\x1218\x134D\x1273\x1275\x0020\x120D\x1304\x1295\x0020\x120B\x134B\x1273\x1275\x1362\x000A"; static const char *locales[] = { "ar_SA.UTF-8", "th_TH.UTF-8", NULL }; int main(int argc, char **argv) { wchar_t buf1[1024]; wchar_t buf2[1024]; char sbuf1[1024]; char sbuf2[1024]; char sxbuf1[1024]; char sxbuf2[1024]; size_t r; int o, j, i, retval, on, jn; const wchar_t *p; char *lctype; char *lcollate; retval = EXIT_SUCCESS; for (i=0 ; locales[i] ; i++) { if (!(lctype = setlocale(LC_CTYPE,locales[i]))) { fprintf(stderr, "setlocale failed\n"); return EXIT_FAILURE; } if (!(lcollate = setlocale(LC_COLLATE,locales[i]))) { fprintf(stderr, "setlocale failed\n"); return EXIT_FAILURE; } wprintf(L"locale: LC_CTYPE=%s LC_COLLATE=%s\n\n", lctype, lcollate); wprintf(L"%5d: %ls ", 1, line1); for (p=line1, j=6 ; *p ; p++) { if (j >= 68) { wprintf(L"\n "); j = 6; } if (((unsigned long) *p) <= 0xffffUL) { wprintf(L" U%04X", (unsigned long) *p); j += 6; } else { wprintf(L" U%08X ", (unsigned long) *p); j += 12; } } wprintf(L"\n"); wprintf(L"%5d: %ls ", 2, line2); for (p=line2, j=6 ; *p ; p++) { if (j >= 68) { wprintf(L"\n "); j = 6; } if (((unsigned long) *p) <= 0xffffUL) { wprintf(L" U%04X", (unsigned long) *p); j += 6; } else { wprintf(L" U%08X ", (unsigned long) *p); j += 12; } } wprintf(L"\n"); wprintf(L"\nwcsxfrm --\n"); if ((r = wcsxfrm(buf1, line1, 1024)) >= 1024) { fprintf(stderr, "wcsxfrm returned %u >= 1024\n", r); return EXIT_FAILURE; } wprintf(L"%5d:", 1); for (j=0 ; j < r ; j++) { if (j && !(j & 7)) { wprintf(L"\n "); } wprintf(L"%9x", buf1[j]); } wprintf(L"\n"); if ((r = wcsxfrm(buf2, line2, 1024)) >= 1024) { fprintf(stderr, "wcsxfrm returned %u >= 1024\n", r); return EXIT_FAILURE; } wprintf(L"%5d:", 2); for (j=0 ; j < r ; j++) { if (j && !(j & 7)) { wprintf(L"\n "); } wprintf(L"%9x", buf2[j]); } wprintf(L"\n"); if (snprintf(sbuf1, sizeof(sbuf1), "%ls", line1) >= sizeof(sbuf1)) { fprintf(stderr, "line1 conversion failed\n"); return EXIT_FAILURE; } if (snprintf(sbuf2, sizeof(sbuf2), "%ls", line2) >= sizeof(sbuf2)) { fprintf(stderr, "line2 conversion failed\n"); return EXIT_FAILURE; } wprintf(L"\nstrxfrm --\n"); if ((r = strxfrm(sxbuf1, sbuf1, sizeof(sxbuf1))) >= sizeof(sxbuf1)) { fprintf(stderr, "wcsxfrm returned %u >= %d\n", r, sizeof(sxbuf1)); return EXIT_FAILURE; } wprintf(L"%5d:", 1); for (j=0 ; j < r ; j++) { if (j && !(j & 7)) { wprintf(L"\n "); } wprintf(L"%9x", sxbuf1[j]); } wprintf(L"\n"); if ((r = strxfrm(sxbuf2, sbuf2, sizeof(sxbuf2))) >= sizeof(sxbuf2)) { fprintf(stderr, "wcsxfrm returned %u >= %d\n", r, sizeof(sxbuf2)); return EXIT_FAILURE; } wprintf(L"%5d:", 2); for (j=0 ; j < r ; j++) { if (j && !(j & 7)) { wprintf(L"\n "); } wprintf(L"%9x", sxbuf2[j]); } wprintf(L"\n"); o = wcscoll(line1, line2); j = wcscmp(buf1, buf2); /* wprintf(L"\nwcscoll=%d wcscmp=%d\n", o, j); */ if ((j != o) && ((j == 0) || ((j < 0) && (o >= 0)) || ((j > 0) && (o <= 0))) ) { wprintf(L"wcscoll and wcscmp(wcsxfrm,wcsxfrm) disagree!"); return EXIT_FAILURE; } wprintf(L"\nwcscoll: "); if (o == 0) { wprintf(L"strings compare equal\n"); } else if (o < 0) { wprintf(L"string1 compares less than string2\n"); o = -1; } else { wprintf(L"string1 compares greater than string2\n"); o = 1; } on = strcoll(sbuf1, sbuf2); jn = strcmp(sxbuf1, sxbuf2); /* wprintf(L"\nstrcoll=%d strcmp=%d\n", o, j); */ if ((jn != on) && ((jn == 0) || ((jn < 0) && (on >= 0)) || ((jn > 0) && (on <= 0))) ) { wprintf(L"strcoll and strcmp(strxfrm,strxfrm) disagree!"); return EXIT_FAILURE; } wprintf(L"strcoll: "); if (on == 0) { wprintf(L"strings compare equal\n"); } else if (on < 0) { wprintf(L"string1 compares less than string2\n"); on = -1; } else { wprintf(L"string1 compares greater than string2\n"); on = 1; } if (o != on) { wprintf(L"wcscoll and strscoll disagree!\n"); retval = EXIT_FAILURE; } wprintf(L"\n"); } return retval; }