| Index: src/common/tuklib_mbstr_width.c
|
| ===================================================================
|
| --- src/common/tuklib_mbstr_width.c (revision 0)
|
| +++ src/common/tuklib_mbstr_width.c (revision 0)
|
| @@ -0,0 +1,64 @@
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +/// \file tuklib_mstr_width.c
|
| +/// \brief Calculate width of a multibyte string
|
| +//
|
| +// Author: Lasse Collin
|
| +//
|
| +// This file has been put into the public domain.
|
| +// You can do whatever you want with this file.
|
| +//
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#include "tuklib_mbstr.h"
|
| +
|
| +#if defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
|
| +# include <wchar.h>
|
| +#endif
|
| +
|
| +
|
| +extern size_t
|
| +tuklib_mbstr_width(const char *str, size_t *bytes)
|
| +{
|
| + const size_t len = strlen(str);
|
| + if (bytes != NULL)
|
| + *bytes = len;
|
| +
|
| +#if !(defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH))
|
| + // In single-byte mode, the width of the string is the same
|
| + // as its length.
|
| + return len;
|
| +
|
| +#else
|
| + mbstate_t state;
|
| + memset(&state, 0, sizeof(state));
|
| +
|
| + size_t width = 0;
|
| + size_t i = 0;
|
| +
|
| + // Convert one multibyte character at a time to wchar_t
|
| + // and get its width using wcwidth().
|
| + while (i < len) {
|
| + wchar_t wc;
|
| + const size_t ret = mbrtowc(&wc, str + i, len - i, &state);
|
| + if (ret < 1 || ret > len)
|
| + return (size_t)-1;
|
| +
|
| + i += ret;
|
| +
|
| + const int wc_width = wcwidth(wc);
|
| + if (wc_width < 0)
|
| + return (size_t)-1;
|
| +
|
| + width += wc_width;
|
| + }
|
| +
|
| + // Require that the string ends in the initial shift state.
|
| + // This way the caller can be combine the string with other
|
| + // strings without needing to worry about the shift states.
|
| + if (!mbsinit(&state))
|
| + return (size_t)-1;
|
| +
|
| + return width;
|
| +#endif
|
| +}
|
|
|
| Property changes on: src/common/tuklib_mbstr_width.c
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|