yum...@gmail.com (Yuriy M. Kaminskiy)
writes:

> However, not everywhere; this code auto-detects column width:
>           if( w==0 ){
>             w = strlen30(azCol[i] ? azCol[i] : "");
>             if( w<10 ) w = 10;
>             n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
>             if( w<n ) w = n;
>           }
> ... and it counts *bytes*, not *characters*.

Patch below fixes this.

Test:
.mode column
.header on
select 'asdfasdasdas' as [aaaйцукйцкуйй], 'asdf' as bbb union all select
'фцвафывафывафываф' as aaa, 'ываыфафывафывавф' as bbb order by 1 desc;
select 'asdfasdasdas' as [aaaйцукйцкуйй], 'asdf' as bbb union all select
'фцвафывафывафываф' as aaa, 'ываыфафывафывавф' as bbb order by 1 asc;

=== cut shell-column-utf8.patch ===
The author or authors of this code dedicate any and all copyright interest
in this code to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and successors.
We intend this dedication to be an overt act of relinquishment in perpetuity
of all present and future rights to this code under copyright law.

Signed-off-by: Yuriy M. Kaminskiy <yum...@gmail.com>

Index: sqlite3-3.19.2/src/shell.c
===================================================================
--- sqlite3-3.19.2.orig/src/shell.c
+++ sqlite3-3.19.2/src/shell.c
@@ -505,6 +505,17 @@ static int strlen30(const char *z){
 }
 
 /*
+** Compute a utf-8 string length (in characters rather than bytes)
+** that is limited to what can be stored in lower 30 bits of a 32-bit
+** signed integer.
+*/
+static int utf8_strlen30(const char *z){
+  const char *z2 = z;
+  while( *z2 ){ z += (*z2 & 0xc0) == 0x80;  z2++; }
+  return 0x3fffffff & (int)(z2 - z);
+}
+
+/*
 ** This routine reads a line of text from FILE in, stores
 ** the text in memory obtained from malloc() and returns a pointer
 ** to the text.  NULL is returned at end of file, or if malloc()
@@ -1912,9 +1923,9 @@ static int shell_callback(
             w = 0;
           }
           if( w==0 ){
-            w = strlen30(azCol[i] ? azCol[i] : "");
+            w = utf8_strlen30(azCol[i] ? azCol[i] : "");
             if( w<10 ) w = 10;
-            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
+            n = utf8_strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
             if( w<n ) w = n;
           }
           if( i<ArraySize(p->actualWidth) ){
@@ -1949,8 +1960,8 @@ static int shell_callback(
         }else{
            w = 10;
         }
-        if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
-          w = strlen30(azArg[i]);
+        if( p->cMode==MODE_Explain && azArg[i] && utf8_strlen30(azArg[i])>w ){
+          w = utf8_strlen30(azArg[i]);
         }
         if( i==1 && p->aiIndent && p->pStmt ){
           if( p->iIndent<p->nIndent ){

_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to