Fossil SCM
When translating UTF8 text for display on the console, use the codepage obtained from GetConsoleCP(), not the CP_ACP code page that is used for system calls.
Commit
55b32701a573b63509701aab405c2d424ce0ac62
Parent
70743ebae5c3bb9…
2 files changed
+50
-4
+1
-2
+50
-4
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -695,14 +695,18 @@ | ||
| 695 | 695 | /************************************************************************** |
| 696 | 696 | ** The following routines translate between MBCS and UTF8 on windows. |
| 697 | 697 | ** Since everything is always UTF8 on unix, these routines are no-ops |
| 698 | 698 | ** there. |
| 699 | 699 | */ |
| 700 | +#ifdef _WIN32 | |
| 701 | +# include <windows.h> | |
| 702 | +#endif | |
| 700 | 703 | |
| 701 | 704 | /* |
| 702 | -** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() | |
| 703 | -** to deallocate any memory used to store the returned pointer when done. | |
| 705 | +** Translate MBCS to UTF8. Return a pointer to the translated text. | |
| 706 | +** Call fossil_mbcs_free() to deallocate any memory used to store the | |
| 707 | +** returned pointer when done. | |
| 704 | 708 | */ |
| 705 | 709 | char *fossil_mbcs_to_utf8(const char *zMbcs){ |
| 706 | 710 | #ifdef _WIN32 |
| 707 | 711 | extern char *sqlite3_win32_mbcs_to_utf8(const char*); |
| 708 | 712 | return sqlite3_win32_mbcs_to_utf8(zMbcs); |
| @@ -710,17 +714,59 @@ | ||
| 710 | 714 | return (char*)zMbcs; /* No-op on unix */ |
| 711 | 715 | #endif |
| 712 | 716 | } |
| 713 | 717 | |
| 714 | 718 | /* |
| 715 | -** Translate UTF8 to MBCS. Return a pointer. Call fossil_mbcs_free() | |
| 716 | -** to deallocate any memory used to store the returned pointer when done. | |
| 719 | +** Translate UTF8 to MBCS for use in system calls. Return a pointer to the | |
| 720 | +** translated text.. Call fossil_mbcs_free() to deallocate any memory | |
| 721 | +** used to store the returned pointer when done. | |
| 717 | 722 | */ |
| 718 | 723 | char *fossil_utf8_to_mbcs(const char *zUtf8){ |
| 719 | 724 | #ifdef _WIN32 |
| 720 | 725 | extern char *sqlite3_win32_utf8_to_mbcs(const char*); |
| 721 | 726 | return sqlite3_win32_utf8_to_mbcs(zUtf8); |
| 727 | +#else | |
| 728 | + return (char*)zUtf8; /* No-op on unix */ | |
| 729 | +#endif | |
| 730 | +} | |
| 731 | + | |
| 732 | +/* | |
| 733 | +** Translate UTF8 to MBCS for display on the console. Return a pointer to the | |
| 734 | +** translated text.. Call fossil_mbcs_free() to deallocate any memory | |
| 735 | +** used to store the returned pointer when done. | |
| 736 | +*/ | |
| 737 | +char *fossil_utf8_to_console(const char *zUtf8){ | |
| 738 | +#ifdef _WIN32 | |
| 739 | + int nChar, nByte; | |
| 740 | + WCHAR *zUnicode; /* Unicode version of zUtf8 */ | |
| 741 | + char *zConsole; /* Console version of zUtf8 */ | |
| 742 | + int codepage; /* Console code page */ | |
| 743 | + | |
| 744 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); | |
| 745 | + zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); | |
| 746 | + if( zUnicode==0 ){ | |
| 747 | + return 0; | |
| 748 | + } | |
| 749 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); | |
| 750 | + if( nChar==0 ){ | |
| 751 | + free(zUnicode); | |
| 752 | + return 0; | |
| 753 | + } | |
| 754 | + codepage = GetConsoleCP(); | |
| 755 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); | |
| 756 | + zConsole = malloc( nByte ); | |
| 757 | + if( zConsole==0 ){ | |
| 758 | + free(zUnicode); | |
| 759 | + return 0; | |
| 760 | + } | |
| 761 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); | |
| 762 | + free(zUnicode); | |
| 763 | + if( nByte == 0 ){ | |
| 764 | + free(zConsole); | |
| 765 | + zConsole = 0; | |
| 766 | + } | |
| 767 | + return zConsole; | |
| 722 | 768 | #else |
| 723 | 769 | return (char*)zUtf8; /* No-op on unix */ |
| 724 | 770 | #endif |
| 725 | 771 | } |
| 726 | 772 | |
| 727 | 773 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -695,14 +695,18 @@ | |
| 695 | /************************************************************************** |
| 696 | ** The following routines translate between MBCS and UTF8 on windows. |
| 697 | ** Since everything is always UTF8 on unix, these routines are no-ops |
| 698 | ** there. |
| 699 | */ |
| 700 | |
| 701 | /* |
| 702 | ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() |
| 703 | ** to deallocate any memory used to store the returned pointer when done. |
| 704 | */ |
| 705 | char *fossil_mbcs_to_utf8(const char *zMbcs){ |
| 706 | #ifdef _WIN32 |
| 707 | extern char *sqlite3_win32_mbcs_to_utf8(const char*); |
| 708 | return sqlite3_win32_mbcs_to_utf8(zMbcs); |
| @@ -710,17 +714,59 @@ | |
| 710 | return (char*)zMbcs; /* No-op on unix */ |
| 711 | #endif |
| 712 | } |
| 713 | |
| 714 | /* |
| 715 | ** Translate UTF8 to MBCS. Return a pointer. Call fossil_mbcs_free() |
| 716 | ** to deallocate any memory used to store the returned pointer when done. |
| 717 | */ |
| 718 | char *fossil_utf8_to_mbcs(const char *zUtf8){ |
| 719 | #ifdef _WIN32 |
| 720 | extern char *sqlite3_win32_utf8_to_mbcs(const char*); |
| 721 | return sqlite3_win32_utf8_to_mbcs(zUtf8); |
| 722 | #else |
| 723 | return (char*)zUtf8; /* No-op on unix */ |
| 724 | #endif |
| 725 | } |
| 726 | |
| 727 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -695,14 +695,18 @@ | |
| 695 | /************************************************************************** |
| 696 | ** The following routines translate between MBCS and UTF8 on windows. |
| 697 | ** Since everything is always UTF8 on unix, these routines are no-ops |
| 698 | ** there. |
| 699 | */ |
| 700 | #ifdef _WIN32 |
| 701 | # include <windows.h> |
| 702 | #endif |
| 703 | |
| 704 | /* |
| 705 | ** Translate MBCS to UTF8. Return a pointer to the translated text. |
| 706 | ** Call fossil_mbcs_free() to deallocate any memory used to store the |
| 707 | ** returned pointer when done. |
| 708 | */ |
| 709 | char *fossil_mbcs_to_utf8(const char *zMbcs){ |
| 710 | #ifdef _WIN32 |
| 711 | extern char *sqlite3_win32_mbcs_to_utf8(const char*); |
| 712 | return sqlite3_win32_mbcs_to_utf8(zMbcs); |
| @@ -710,17 +714,59 @@ | |
| 714 | return (char*)zMbcs; /* No-op on unix */ |
| 715 | #endif |
| 716 | } |
| 717 | |
| 718 | /* |
| 719 | ** Translate UTF8 to MBCS for use in system calls. Return a pointer to the |
| 720 | ** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 721 | ** used to store the returned pointer when done. |
| 722 | */ |
| 723 | char *fossil_utf8_to_mbcs(const char *zUtf8){ |
| 724 | #ifdef _WIN32 |
| 725 | extern char *sqlite3_win32_utf8_to_mbcs(const char*); |
| 726 | return sqlite3_win32_utf8_to_mbcs(zUtf8); |
| 727 | #else |
| 728 | return (char*)zUtf8; /* No-op on unix */ |
| 729 | #endif |
| 730 | } |
| 731 | |
| 732 | /* |
| 733 | ** Translate UTF8 to MBCS for display on the console. Return a pointer to the |
| 734 | ** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 735 | ** used to store the returned pointer when done. |
| 736 | */ |
| 737 | char *fossil_utf8_to_console(const char *zUtf8){ |
| 738 | #ifdef _WIN32 |
| 739 | int nChar, nByte; |
| 740 | WCHAR *zUnicode; /* Unicode version of zUtf8 */ |
| 741 | char *zConsole; /* Console version of zUtf8 */ |
| 742 | int codepage; /* Console code page */ |
| 743 | |
| 744 | nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); |
| 745 | zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); |
| 746 | if( zUnicode==0 ){ |
| 747 | return 0; |
| 748 | } |
| 749 | nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); |
| 750 | if( nChar==0 ){ |
| 751 | free(zUnicode); |
| 752 | return 0; |
| 753 | } |
| 754 | codepage = GetConsoleCP(); |
| 755 | nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); |
| 756 | zConsole = malloc( nByte ); |
| 757 | if( zConsole==0 ){ |
| 758 | free(zUnicode); |
| 759 | return 0; |
| 760 | } |
| 761 | nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); |
| 762 | free(zUnicode); |
| 763 | if( nByte == 0 ){ |
| 764 | free(zConsole); |
| 765 | zConsole = 0; |
| 766 | } |
| 767 | return zConsole; |
| 768 | #else |
| 769 | return (char*)zUtf8; /* No-op on unix */ |
| 770 | #endif |
| 771 | } |
| 772 | |
| 773 |
+1
-2
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -807,21 +807,20 @@ | ||
| 807 | 807 | ** if the output is going to the screen. If output is redirected into |
| 808 | 808 | ** a file, no translation occurs. No translation ever occurs on unix. |
| 809 | 809 | */ |
| 810 | 810 | void fossil_puts(const char *z, int toStdErr){ |
| 811 | 811 | #if defined(_WIN32) |
| 812 | - extern char *sqlite3_win32_utf8_to_mbcs(const char*); | |
| 813 | 812 | static int once = 1; |
| 814 | 813 | static int istty[2]; |
| 815 | 814 | char *zToFree = 0; |
| 816 | 815 | if( once ){ |
| 817 | 816 | istty[0] = _isatty(fileno(stdout)); |
| 818 | 817 | istty[1] = _isatty(fileno(stderr)); |
| 819 | 818 | once = 0; |
| 820 | 819 | } |
| 821 | 820 | assert( toStdErr==0 || toStdErr==1 ); |
| 822 | - if( istty[toStdErr] ) z = zToFree = sqlite3_win32_utf8_to_mbcs(z); | |
| 821 | + if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z); | |
| 823 | 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 824 | 823 | free(zToFree); |
| 825 | 824 | #else |
| 826 | 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 827 | 826 | #endif |
| 828 | 827 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -807,21 +807,20 @@ | |
| 807 | ** if the output is going to the screen. If output is redirected into |
| 808 | ** a file, no translation occurs. No translation ever occurs on unix. |
| 809 | */ |
| 810 | void fossil_puts(const char *z, int toStdErr){ |
| 811 | #if defined(_WIN32) |
| 812 | extern char *sqlite3_win32_utf8_to_mbcs(const char*); |
| 813 | static int once = 1; |
| 814 | static int istty[2]; |
| 815 | char *zToFree = 0; |
| 816 | if( once ){ |
| 817 | istty[0] = _isatty(fileno(stdout)); |
| 818 | istty[1] = _isatty(fileno(stderr)); |
| 819 | once = 0; |
| 820 | } |
| 821 | assert( toStdErr==0 || toStdErr==1 ); |
| 822 | if( istty[toStdErr] ) z = zToFree = sqlite3_win32_utf8_to_mbcs(z); |
| 823 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 824 | free(zToFree); |
| 825 | #else |
| 826 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 827 | #endif |
| 828 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -807,21 +807,20 @@ | |
| 807 | ** if the output is going to the screen. If output is redirected into |
| 808 | ** a file, no translation occurs. No translation ever occurs on unix. |
| 809 | */ |
| 810 | void fossil_puts(const char *z, int toStdErr){ |
| 811 | #if defined(_WIN32) |
| 812 | static int once = 1; |
| 813 | static int istty[2]; |
| 814 | char *zToFree = 0; |
| 815 | if( once ){ |
| 816 | istty[0] = _isatty(fileno(stdout)); |
| 817 | istty[1] = _isatty(fileno(stderr)); |
| 818 | once = 0; |
| 819 | } |
| 820 | assert( toStdErr==0 || toStdErr==1 ); |
| 821 | if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z); |
| 822 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 823 | free(zToFree); |
| 824 | #else |
| 825 | fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); |
| 826 | #endif |
| 827 |