<<< Date Index >>>     <<< Thread Index >>>

Re: mutt_FormatString() not multibyte-aware



* Sat Jul  8 2006 Rocco Rutte <pdmef@xxxxxxx>
> * Ludolf Holzheid [06-07-07 21:18:52 +0200] wrote:
> 
> >(I wonder why Tamo didn't jump into that earlier -- Maybe he's just
> >tired of explaining to the Europeans there are other scripts than
> >Latin.)
> 
> I understand and know that perfectly well. Maybe it's just that I didn't 
> make myself clear enough.

I believe that Rocco knows multibyte issues well (yes,
quite better than I). I said nothing against his opinion
just because I didn't find anything bad.

I can write bogus wc-funcs to complete my previous hack,
but I have no idea which is better (mine or Rocco's).
At this moment, mine is a _little_ better because he hasn't
posted a patch. I hope he will find a best way.

-- 
tamo

--- mbyte.c
+++ mbyte.c
@@ -463,6 +463,94 @@ size_t utf8rtowc (wchar_t *pwc, const ch
   return (size_t)-2;
 }
 
+/* wcswidth by Markus Kuhn -- 2000-02-08 -- public domain */
+int wcswidth(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = wcwidth(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
+
+/* mbstowcs hack - may violate POSIX */
+size_t mbstowcs (wchar_t *pwcs, const char *s, size_t n)
+{
+  mbstate_t st;
+  size_t k;
+  wchar_t wc;
+  wchar_t *p = pwcs;
+
+  memset (&st, 0, sizeof (st));
+  for (; (k = mbrtowc (&wc, s, MB_LEN_MAX, &st)); s += k)
+  {
+    if (k == (size_t)(-1) || k == (size_t)(-2))
+    {
+      errno = EILSEQ;
+      return (size_t)(-1);
+    }
+    if (pwcs)
+    {
+      if (!n)
+       break;
+      *p++ = wc;
+      n--;
+    }
+  }
+  if (n && pwcs)
+    *p = 0;
+  return (p - pwcs);
+}
+
+/* wcstombs hack - may violate POSIX */
+size_t wcstombs (char *s, const wchar_t *pwcs, size_t n)
+{
+  size_t l, r = 0;
+  char buf[MB_LEN_MAX];
+
+  for (;*pwcs; pwcs++)
+  {
+    l = wcrtomb (buf, *pwcs, NULL);
+    if (l == (size_t)(-1))
+    {
+      errno = EILSEQ;
+      return l;
+    }
+    if (s)
+    {
+      if (n <= l)
+       break;
+      memcpy (s, buf, l);
+      s += l;
+      n -= l;
+    }
+    r += l;
+  }
+  if (s && n)
+    *s = '\0';
+  return r;
+}
+
+size_t wcslen (const wchar_t *s)
+{
+  size_t l = 0;
+  while (*s++)
+    l++;
+  return l;
+}
+
+wchar_t * wmemcpy (wchar_t *s1, const wchar_t *s2, size_t n)
+{
+  wchar_t *o = s1;
+  while (n--)
+    *s1++ = *s2++;
+  return o;
+}
+
 #endif /* !HAVE_WC_FUNCS */
 
 wchar_t replacement_char (void)
--- mbyte.h
+++ mbyte.h
@@ -19,6 +19,11 @@ wint_t towupper (wint_t wc);
 wint_t towupper (wint_t wc);
 wint_t towlower (wint_t wc);
 int wcwidth (wchar_t wc);
+int wcswidth(const wchar_t *pwcs, size_t n);
+size_t mbstowcs (wchar_t *pwcs, const char *s, size_t n);
+size_t wcstombs (char *s, const wchar_t *pwcs, size_t n);
+size_t wcslen (const wchar_t *s);
+wchar_t * wmemcpy (wchar_t *s1, const wchar_t *s2, size_t n);
 # endif /* !HAVE_WC_FUNCS */