Fix the ".column" output mode in the command-line shell so that it correctly

counts and formats multi-byte UTF characters.

FossilOrigin-Name: f508aff8d1782abdff4d03726ae098607a0ee6cfd2e35b130097ee5043e98960
This commit is contained in:
drh 2017-04-17 13:18:42 +00:00
parent b6d5a43b8a
commit 6887e8facd
3 changed files with 41 additions and 23 deletions

View File

@ -1,5 +1,5 @@
C In\sthe\sshowwal\scommand-line\stool,\sfor\sunix\sbuilds,\sif\sthe\nauxiliary\sargument\sis\sof\nthe\sform\s"Ntruncate"\swhere\s"N"\sis\sa\sframe\snumber,\sthen\struncate\sthe\sWAL\nfile\safter\sthe\sN-th\sframe.
D 2017-04-16T22:41:49.287
C Fix\sthe\s".column"\soutput\smode\sin\sthe\scommand-line\sshell\sso\sthat\sit\scorrectly\ncounts\sand\sformats\smulti-byte\sUTF\scharacters.
D 2017-04-17T13:18:42.048
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6
@ -403,7 +403,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 4588dcfb0fa430012247a209ba08e17904dd32ec7690e9cb6c85e0ef012b0518
F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d
F src/shell.c 21b79c0e1b93f8e35fd7b4087d6ba438326c3d7e285d0dd51dfd741475f858a1
F src/sqlite.h.in 40233103e3e4e10f8a63523498d0259d232e42aba478e2d3fb914799185aced6
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
@ -1573,7 +1573,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P d7b9813cb17615c3d00afd6994a4309d6d48c8e924b6cd813c543e1fa65c7719
R 8c1cbe1045ee7677fda3e059322e3580
P 90015df30655d884ecf7ae61e588824696954252dc6b1a5f78cf2de8cb236104
R f3fe31d09ab4f188db4ba42e5036f494
U drh
Z aa5715d42d381110f91b49a6f98fcf69
Z b0a62e79cb4eb34b7f5f7cf838722768

View File

@ -1 +1 @@
90015df30655d884ecf7ae61e588824696954252dc6b1a5f78cf2de8cb236104
f508aff8d1782abdff4d03726ae098607a0ee6cfd2e35b130097ee5043e98960

View File

@ -427,6 +427,36 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
}
#endif
/*
** Output string zUtf to stream pOut as w characters. If w is negative,
** then right-justify the text. W is the width in UTF-8 characters, not
** in bytes. This is different from the %*.*s specification in printf
** since with %*.*s the width is measured in bytes, not characters.
*/
static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
int i;
int n;
int aw = w<0 ? -w : w;
char zBuf[1000];
if( aw>sizeof(zBuf)/3 ) aw = sizeof(zBuf)/3;
for(i=n=0; zUtf[i]; i++){
if( (zUtf[i]&0xc0)!=0x80 ){
n++;
if( n==aw ){
do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
break;
}
}
}
if( n>=aw ){
utf8_printf(pOut, "%.*s", i, zUtf);
}else if( w<0 ){
utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
}else{
utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
}
}
/*
** Determines if a string is a number of not.
@ -1878,13 +1908,8 @@ static int shell_callback(
p->actualWidth[i] = w;
}
if( showHdr ){
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
i==nArg-1 ? rowSep : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
i==nArg-1 ? rowSep : " ");
}
utf8_width_print(p->out, w, azCol[i]);
utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
}
}
if( showHdr ){
@ -1920,15 +1945,8 @@ static int shell_callback(
}
p->iIndent++;
}
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? rowSep : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? rowSep : " ");
}
utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
}
break;
}