blob: 042c9f14069bc27c2957148d2881e28d51f76cff [file] [log] [blame]
Chet Rameyac50fba2014-02-26 09:36:43 -05001/* Copyright (C) 2001, 2006, 2009, 2010, 2012 Free Software Foundation, Inc.
Chet Ramey495aee42011-11-22 19:11:26 -05002
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16
17#include <config.h>
18
19#if defined (HANDLE_MULTIBYTE)
20#include <stdlib.h>
21#include <limits.h>
22
23#include <shmbutil.h>
24#include <shmbchar.h>
25
26#if IS_BASIC_ASCII
27
28/* Bit table of characters in the ISO C "basic character set". */
29const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] =
30{
31 0x00001a00, /* '\t' '\v' '\f' */
32 0xffffffef, /* ' '...'#' '%'...'?' */
33 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */
34 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */
35 /* The remaining bits are 0. */
36};
37
38#endif /* IS_BASIC_ASCII */
39
40size_t
41mbstrlen (s)
42 const char *s;
43{
44 size_t clen, nc;
45 mbstate_t mbs = { 0 }, mbsbak = { 0 };
46 int f;
47
48 nc = 0;
49 while (*s && (clen = (f = is_basic (*s)) ? 1 : mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
50 {
51 if (MB_INVALIDCH(clen))
52 {
53 clen = 1; /* assume single byte */
54 mbs = mbsbak;
55 }
56
57 if (f == 0)
58 mbsbak = mbs;
59
60 s += clen;
61 nc++;
62 }
63 return nc;
64}
65
66/* Return pointer to first multibyte char in S, or NULL if none. */
67char *
68mbsmbchar (s)
69 const char *s;
70{
71 char *t;
72 size_t clen;
73 mbstate_t mbs = { 0 };
74
75 for (t = (char *)s; *t; t++)
76 {
77 if (is_basic (*t))
78 continue;
79
80 clen = mbrlen (t, MB_CUR_MAX, &mbs);
81
82 if (clen == 0)
83 return 0;
84 if (MB_INVALIDCH(clen))
85 continue;
86
87 if (clen > 1)
88 return t;
89 }
90 return 0;
91}
Chet Rameyac50fba2014-02-26 09:36:43 -050092
93int
94sh_mbsnlen(src, srclen, maxlen)
95 const char *src;
96 size_t srclen;
97 int maxlen;
98{
99 int count;
100 int sind;
101 DECLARE_MBSTATE;
102
103 for (sind = count = 0; src[sind]; )
104 {
105 count++; /* number of multibyte characters */
106 ADVANCE_CHAR (src, srclen, sind);
107 if (sind > maxlen)
108 break;
109 }
110
111 return count;
112}
Chet Ramey495aee42011-11-22 19:11:26 -0500113#endif