c5badc149a264c6a708a7374e7d405b817460ab8
[platform/upstream/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