mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Avoid undesirable NL to CRLF translation when doing binary output to the
Windows console. FossilOrigin-Name: d25bdce36abed95524ad058a277aba7bb17270e7ff1476474713dbc29742c762
This commit is contained in:
@ -67,6 +67,31 @@
|
||||
# define IsConsole(fd) 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Global variables determine if simulated O_BINARY mode is to be
|
||||
** used for stdout or other, respectively. Simulated O_BINARY mode
|
||||
** means the mode is usually O_BINARY, but switches to O_U8TEXT for
|
||||
** unicode characters U+0080 or greater (any character that has a
|
||||
** multi-byte representation in UTF-8). This is the only way we
|
||||
** have found to render Unicode characters on a Windows console while
|
||||
** at the same time avoiding undesirable \n to \r\n translation.
|
||||
*/
|
||||
static int simBinaryStdout = 0;
|
||||
static int simBinaryOther = 0;
|
||||
|
||||
|
||||
/*
|
||||
** Determine if simulated binary mode should be used for output to fd
|
||||
*/
|
||||
static int UseBinaryWText(FILE *fd){
|
||||
if( fd==stdout || fd==stderr ){
|
||||
return simBinaryStdout;
|
||||
}else{
|
||||
return simBinaryOther;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Work-alike for the fopen() routine from the standard C library.
|
||||
*/
|
||||
@ -88,6 +113,7 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){
|
||||
}
|
||||
free(b1);
|
||||
free(b2);
|
||||
simBinaryOther = 0;
|
||||
return fp;
|
||||
}
|
||||
|
||||
@ -143,13 +169,53 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Send ASCII text as O_BINARY. But for Unicode characters U+0080 and
|
||||
** greater, switch to O_U8TEXT.
|
||||
*/
|
||||
static void piecemealOutput(wchar_t *b1, int sz, FILE *out){
|
||||
int i;
|
||||
wchar_t c;
|
||||
while( sz>0 ){
|
||||
for(i=0; i<sz && b1[i]>=0x80; i++){}
|
||||
if( i>0 ){
|
||||
c = b1[i];
|
||||
b1[i] = 0;
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
fputws(b1, out);
|
||||
fflush(out);
|
||||
b1 += i;
|
||||
b1[0] = c;
|
||||
sz -= i;
|
||||
}else{
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_TEXT);
|
||||
_setmode(_fileno(out), _O_BINARY);
|
||||
fwrite(&b1[0], 1, 1, out);
|
||||
for(i=1; i<sz && b1[i]<0x80; i++){
|
||||
fwrite(&b1[i], 1, 1, out);
|
||||
}
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
b1 += i;
|
||||
sz -= i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Work-alike for fputs() from the standard C library.
|
||||
*/
|
||||
int sqlite3_fputs(const char *z, FILE *out){
|
||||
if( UseWtextForOutput(out) ){
|
||||
if( !UseWtextForOutput(out) ){
|
||||
/* Writing to a file or other destination, just write bytes without
|
||||
** any translation. */
|
||||
return fputs(z, out);
|
||||
}else{
|
||||
/* When writing to the command-prompt in Windows, it is necessary
|
||||
** to use _O_WTEXT input mode and write UTF-16 characters.
|
||||
** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
|
||||
** use O_U8TEXT for everything in text mode.
|
||||
*/
|
||||
int sz = (int)strlen(z);
|
||||
wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) );
|
||||
@ -157,13 +223,13 @@ int sqlite3_fputs(const char *z, FILE *out){
|
||||
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
|
||||
b1[sz] = 0;
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
fputws(b1, out);
|
||||
if( UseBinaryWText(out) ){
|
||||
piecemealOutput(b1, sz, out);
|
||||
}else{
|
||||
fputws(b1, out);
|
||||
}
|
||||
sqlite3_free(b1);
|
||||
return 0;
|
||||
}else{
|
||||
/* Writing to a file or other destination, just write bytes without
|
||||
** any translation. */
|
||||
return fputs(z, out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,6 +271,10 @@ void sqlite3_fsetmode(FILE *fp, int mode){
|
||||
if( !UseWtextForOutput(fp) ){
|
||||
fflush(fp);
|
||||
_setmode(_fileno(fp), mode);
|
||||
}else if( fp==stdout || fp==stderr ){
|
||||
simBinaryStdout = (mode==_O_BINARY);
|
||||
}else{
|
||||
simBinaryOther = (mode==_O_BINARY);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user