]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/shmbchar.c
Bash-4.2 distribution sources and documentation
[thirdparty/bash.git] / lib / sh / shmbchar.c
1 /* Copyright (C) 2001, 2006, 2009, 2010 Free Software Foundation, Inc.
2
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". */
29 const 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
40 size_t
41 mbstrlen (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. */
67 char *
68 mbsmbchar (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 }
92 #endif