From: drh Date: Mon, 17 Apr 2017 13:18:42 +0000 (+0000) Subject: Fix the ".column" output mode in the command-line shell so that it correctly X-Git-Tag: version-3.19.0~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6887e8facd4907f87505eaa830e093f3d19edf8d;p=thirdparty%2Fsqlite.git Fix the ".column" output mode in the command-line shell so that it correctly counts and formats multi-byte UTF characters. FossilOrigin-Name: f508aff8d1782abdff4d03726ae098607a0ee6cfd2e35b130097ee5043e98960 --- diff --git a/manifest b/manifest index 7660e6380e..e78a637233 100644 --- a/manifest +++ b/manifest @@ -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 diff --git a/manifest.uuid b/manifest.uuid index 14a8d9cd9b..a92b1214ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90015df30655d884ecf7ae61e588824696954252dc6b1a5f78cf2de8cb236104 \ No newline at end of file +f508aff8d1782abdff4d03726ae098607a0ee6cfd2e35b130097ee5043e98960 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8341d828c1..15c88061c2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -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; }