Rizin
unix-like reverse engineering framework and cli tools
tuklib_mbstr_width.c
Go to the documentation of this file.
1 //
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
12 
13 #include "tuklib_mbstr.h"
14 #include <string.h>
15 
16 #if defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
17 # include <wchar.h>
18 #endif
19 
20 
21 extern size_t
22 tuklib_mbstr_width(const char *str, size_t *bytes)
23 {
24  const size_t len = strlen(str);
25  if (bytes != NULL)
26  *bytes = len;
27 
28 #if !(defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH))
29  // In single-byte mode, the width of the string is the same
30  // as its length.
31  return len;
32 
33 #else
34  mbstate_t state;
35  memset(&state, 0, sizeof(state));
36 
37  size_t width = 0;
38  size_t i = 0;
39 
40  // Convert one multibyte character at a time to wchar_t
41  // and get its width using wcwidth().
42  while (i < len) {
43  wchar_t wc;
44  const size_t ret = mbrtowc(&wc, str + i, len - i, &state);
45  if (ret < 1 || ret > len)
46  return (size_t)-1;
47 
48  i += ret;
49 
50  const int wc_width = wcwidth(wc);
51  if (wc_width < 0)
52  return (size_t)-1;
53 
54  width += (size_t)wc_width;
55  }
56 
57  // Require that the string ends in the initial shift state.
58  // This way the caller can be combine the string with other
59  // strings without needing to worry about the shift states.
60  if (!mbsinit(&state))
61  return (size_t)-1;
62 
63  return width;
64 #endif
65 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static ut8 bytes[32]
Definition: asm_arc.c:23
#define NULL
Definition: cris-opc.c:27
return memset(p, 0, total)
int size_t
Definition: sftypes.h:40
Definition: dis.h:43
int width
Definition: main.c:10
Utility functions for handling multibyte strings.
size_t tuklib_mbstr_width(const char *str, size_t *bytes)
Get the number of columns needed for the multibyte string.