On Mon, Jan 02, 2006 at 04:47:31PM -0500, [EMAIL PROTECTED] wrote:
>
> I suppose you could argue that this is a bug in the command-line
> shell.  I won't contradict you.  But being a monolingual american,
> I have no clue how to reproduce the problem, much less fix it.

You just need to compensate for the discrepancy between the number of
chars in a multibyte string and the actual amount of space (in
columns) that is used when printing that multibyte string.  The
attached patch is one way to do this.  It uses wcswidth(), which is a
UNIX98 function, so this isn't extremely portable.  Therefore, I
wouldn't recommend applying it without adding some autoconf-style
detection and stub out wstrlen() for platforms that don't have the
needed functions.

Cheers,

Matt
-- 
Matt Wilson
rPath, Inc.
[EMAIL PROTECTED]
Index: src/shell.c
===================================================================
RCS file: /sqlite/sqlite/src/shell.c,v
retrieving revision 1.130
diff -u -r1.130 shell.c
--- src/shell.c 29 Dec 2005 12:53:10 -0000      1.130
+++ src/shell.c 2 Jan 2006 23:38:52 -0000
@@ -20,6 +20,9 @@
 #include <assert.h>
 #include "sqlite3.h"
 #include <ctype.h>
+#include <locale.h>
+#include <wchar.h>
+
 
 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
 # include <signal.h>
@@ -263,6 +266,31 @@
 */
 #define ArraySize(X)  (sizeof(X)/sizeof(X[0]))
 
+/* return the width (number of printed columns) for a multibyte string */
+static int wstrlen(const char *s){
+  size_t len;
+  wchar_t *wcs = NULL;
+  int width, slen;
+
+  /* first figure out how much space we need for the wide char version
+     of the string */
+  len = mbstowcs(NULL, s, 0) + 1;
+  /* we'll need the length of the char string to fall back on */
+  slen = strlen(s);
+  if (-1 == len)
+    /* multibyte conversion failure, fall back to strlen */
+    return slen;
+  wcs = malloc(len * sizeof(wchar_t));
+  if (NULL == wcs) {
+    fprintf(stderr,"Out of memory!\n");
+    exit(1);
+  }
+  mbstowcs(wcs, s, len);
+  width = wcswidth(wcs, slen);
+  free(wcs);
+  return width;
+}
+
 /*
 ** Output the given string as a quoted string using SQL quoting conventions.
 */
@@ -438,6 +466,11 @@
         }else{
            w = 10;
         }
+
+        if (azArg[i]) {
+          /* compensate for multibyte strings */
+          w += strlen(azArg[i]) - wstrlen(azArg[i]);
+        }
         fprintf(p->out,"%-*.*s%s",w,w,
             azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
       }
@@ -1665,6 +1698,7 @@
 
   Argv0 = argv[0];
   main_init(&data);
+  setlocale(LC_ALL, "");
 
   /* Make sure we have a valid signal handler early, before anything
   ** else is done.

Reply via email to