annotate lib/mbrtowc.c @ 40057:b06060465f09

maint: Run 'make update-copyright'
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 01 Jan 2019 00:25:11 +0100
parents 46aa87a2631e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Convert multibyte character to wide character.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 39704
diff changeset
2 Copyright (C) 1999-2002, 2005-2019 Free Software Foundation, Inc.
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2008.
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18914
diff changeset
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 /* Specification. */
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include <wchar.h>
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
23 #if C_LOCALE_MAYBE_EILSEQ
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
24 # include "hard-locale.h"
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
25 # include <locale.h>
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
26 #endif
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
27
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
28 #if GNULIB_defined_mbstate_t
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
29 /* Implement mbrtowc() on top of mbtowc(). */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
31 # include <errno.h>
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
32 # include <stdlib.h>
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
33
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
34 # include "localcharset.h"
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
35 # include "streq.h"
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
36 # include "verify.h"
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
38 # ifndef FALLTHROUGH
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
39 # if __GNUC__ < 7
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
40 # define FALLTHROUGH ((void) 0)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
41 # else
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
42 # define FALLTHROUGH __attribute__ ((__fallthrough__))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
43 # endif
18914
886945d1fa95 manywarnings: update for GCC 7
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
44 # endif
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
45
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
46 /* Returns a classification of special values of the encoding of the current
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
47 locale. */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
48 typedef enum {
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
49 enc_other, /* other */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
50 enc_utf8, /* UTF-8 */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
51 enc_eucjp, /* EUC-JP */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
52 enc_94, /* EUC-KR, GB2312, BIG5 */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
53 enc_euctw, /* EUC-TW */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
54 enc_gb18030, /* GB18030 */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
55 enc_sjis /* SJIS */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
56 } enc_t;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
57 static inline enc_t
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
58 locale_enc (void)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
59 {
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
60 const char *encoding = locale_charset ();
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
61 if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
62 return enc_utf8;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
63 if (STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
64 return enc_eucjp;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
65 if (STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
66 || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
67 || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
68 return enc_94;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
69 if (STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
70 return enc_euctw;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
71 if (STREQ_OPT (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
72 return enc_gb18030;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
73 if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0))
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
74 return enc_sjis;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
75 return enc_other;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
76 }
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
77
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
78 #if GNULIB_WCHAR_SINGLE
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
79 /* When we know that the locale does not change, provide a speedup by
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
80 caching the value of locale_enc. */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
81 static int cached_locale_enc = -1;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
82 static inline enc_t
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
83 locale_enc_cached (void)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
84 {
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
85 if (cached_locale_enc < 0)
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
86 cached_locale_enc = locale_enc ();
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
87 return cached_locale_enc;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
88 }
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
89 #else
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
90 /* By default, don't make assumptions, hence no caching. */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
91 # define locale_enc_cached locale_enc
18914
886945d1fa95 manywarnings: update for GCC 7
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
92 #endif
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93
10909
796f25c7bd1a Verify an assumption.
Bruno Haible <bruno@clisp.org>
parents: 10906
diff changeset
94 verify (sizeof (mbstate_t) >= 4);
796f25c7bd1a Verify an assumption.
Bruno Haible <bruno@clisp.org>
parents: 10906
diff changeset
95
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 static char internal_state[4];
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 size_t
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 {
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 char *pstate = (char *)ps;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 if (s == NULL)
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 {
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 pwc = NULL;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 s = "";
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 n = 1;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 }
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 if (n == 0)
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 return (size_t)(-2);
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 /* Here n > 0. */
14374
85a5ffbc0cb3 mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
114
85a5ffbc0cb3 mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
115 if (pstate == NULL)
85a5ffbc0cb3 mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
116 pstate = internal_state;
85a5ffbc0cb3 mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
117
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 {
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119 size_t nstate = pstate[0];
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 char buf[4];
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 const char *p;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 size_t m;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 switch (nstate)
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 {
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 case 0:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
127 p = s;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
128 m = n;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
129 break;
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 case 3:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
131 buf[2] = pstate[3];
18914
886945d1fa95 manywarnings: update for GCC 7
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
132 FALLTHROUGH;
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 case 2:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
134 buf[1] = pstate[2];
18914
886945d1fa95 manywarnings: update for GCC 7
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
135 FALLTHROUGH;
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 case 1:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
137 buf[0] = pstate[1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
138 p = buf;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
139 m = nstate;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
140 buf[m++] = s[0];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
141 if (n >= 2 && m < 4)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
142 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
143 buf[m++] = s[1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
144 if (n >= 3 && m < 4)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
145 buf[m++] = s[2];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
146 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
147 break;
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148 default:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
149 errno = EINVAL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
150 return (size_t)(-1);
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 }
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
152
11211
3070459611d3 Fix comment.
Bruno Haible <bruno@clisp.org>
parents: 11087
diff changeset
153 /* Here m > 0. */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154
13885
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
155 # if __GLIBC__ || defined __UCLIBC__
19192
d86e08b1f555 all: Replace many more http URLs by https URLs. Update stale URLs.
Bruno Haible <bruno@clisp.org>
parents: 19190
diff changeset
156 /* Work around bug <https://sourceware.org/bugzilla/show_bug.cgi?id=9674> */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 mbtowc (NULL, NULL, 0);
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
158 # endif
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 {
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 int res = mbtowc (pwc, p, m);
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 if (res >= 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
163 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
164 if (pwc != NULL && ((*pwc == 0) != (res == 0)))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
165 abort ();
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
166 if (nstate >= (res > 0 ? res : 1))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
167 abort ();
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
168 res -= nstate;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
169 pstate[0] = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
170 return res;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
171 }
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
172
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173 /* mbtowc does not distinguish between invalid and incomplete multibyte
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
174 sequences. But mbrtowc needs to make this distinction.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
175 There are two possible approaches:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
176 - Use iconv() and its return value.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
177 - Use built-in knowledge about the possible encodings.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
178 Given the low quality of implementation of iconv() on the systems that
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
179 lack mbrtowc(), we use the second approach.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
180 The possible encodings are:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
181 - 8-bit encodings,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
182 - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
183 - UTF-8.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
184 Use specialized code for each. */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185 if (m >= 4 || m >= MB_CUR_MAX)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
186 goto invalid;
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187 /* Here MB_CUR_MAX > 1 and 0 < m < 4. */
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
188 switch (locale_enc_cached ())
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
189 {
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
190 case enc_utf8: /* UTF-8 */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
191 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
192 /* Cf. unistr/u8-mblen.c. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
193 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
194
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
195 if (c >= 0xc2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
196 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
197 if (c < 0xe0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
198 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
199 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
200 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
201 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
202 else if (c < 0xf0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
203 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
204 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
205 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
206 if (m == 2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
207 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
208 unsigned char c2 = (unsigned char) p[1];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
210 if ((c2 ^ 0x80) < 0x40
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
211 && (c >= 0xe1 || c2 >= 0xa0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
212 && (c != 0xed || c2 < 0xa0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
213 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
214 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
215 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
216 else if (c <= 0xf4)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
217 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
218 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
219 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
220 else /* m == 2 || m == 3 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
221 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
222 unsigned char c2 = (unsigned char) p[1];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
224 if ((c2 ^ 0x80) < 0x40
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
225 && (c >= 0xf1 || c2 >= 0x90)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
226 && (c < 0xf4 || (c == 0xf4 && c2 < 0x90)))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
227 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
228 if (m == 2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
229 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
230 else /* m == 3 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
231 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
232 unsigned char c3 = (unsigned char) p[2];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
234 if ((c3 ^ 0x80) < 0x40)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
235 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
236 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
237 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
238 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
239 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
240 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
241 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
242 }
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
243
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
244 /* As a reference for this code, you can use the GNU libiconv
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
245 implementation. Look for uses of the RET_TOOFEW macro. */
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
246
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
247 case enc_eucjp: /* EUC-JP */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
248 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
249 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
250 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
251 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
252
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
253 if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
254 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
255 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
256 if (m == 2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
257 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
258 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
259
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
260 if (c == 0x8f)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
261 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
262 unsigned char c2 = (unsigned char) p[1];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
264 if (c2 >= 0xa1 && c2 < 0xff)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
265 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
266 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
267 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
268 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
269 }
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
270
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
271 case enc_94: /* EUC-KR, GB2312, BIG5 */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
272 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
273 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
274 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
275 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
276
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
277 if (c >= 0xa1 && c < 0xff)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
278 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
279 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
280 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
281 }
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
282
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
283 case enc_euctw: /* EUC-TW */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
284 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
285 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
286 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
287 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
288
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
289 if ((c >= 0xa1 && c < 0xff) || c == 0x8e)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
290 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
291 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
292 else /* m == 2 || m == 3 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
293 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
294 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
295
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
296 if (c == 0x8e)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
297 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
298 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
299 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
300 }
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
301
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
302 case enc_gb18030: /* GB18030 */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
303 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
304 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
305 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
306 unsigned char c = (unsigned char) p[0];
11087
05091c173f76 Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents: 10924
diff changeset
307
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
308 if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
309 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
310 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
311 else /* m == 2 || m == 3 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
312 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
313 unsigned char c = (unsigned char) p[0];
11087
05091c173f76 Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents: 10924
diff changeset
314
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
315 if (c >= 0x90 && c <= 0xe3)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
316 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
317 unsigned char c2 = (unsigned char) p[1];
11087
05091c173f76 Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents: 10924
diff changeset
318
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
319 if (c2 >= 0x30 && c2 <= 0x39)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
320 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
321 if (m == 2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
322 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
323 else /* m == 3 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
324 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
325 unsigned char c3 = (unsigned char) p[2];
11087
05091c173f76 Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents: 10924
diff changeset
326
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
327 if (c3 >= 0x81 && c3 <= 0xfe)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
328 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
329 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
330 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
331 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
332 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
333 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
334 }
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
335
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
336 case enc_sjis: /* SJIS */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
337 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
338 if (m == 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
339 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
340 unsigned char c = (unsigned char) p[0];
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
341
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
342 if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
343 || (c >= 0xf0 && c <= 0xf9))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
344 goto incomplete;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
345 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
346 goto invalid;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
347 }
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
348
39704
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
349 default:
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
350 /* An unknown multibyte encoding. */
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
351 goto incomplete;
46aa87a2631e mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
Bruno Haible <bruno@clisp.org>
parents: 39701
diff changeset
352 }
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
353
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
354 incomplete:
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
355 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
356 size_t k = nstate;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
357 /* Here 0 <= k < m < 4. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
358 pstate[++k] = s[0];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
359 if (k < m)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
360 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
361 pstate[++k] = s[1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
362 if (k < m)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
363 pstate[++k] = s[2];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
364 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
365 if (k != m)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
366 abort ();
10906
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
367 }
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
368 pstate[0] = m;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
369 return (size_t)(-2);
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
370
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
371 invalid:
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
372 errno = EILSEQ;
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
373 /* The conversion state is undefined, says POSIX. */
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
374 return (size_t)(-1);
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
375 }
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
376 }
6e283a40b2c1 New module 'mbrtowc'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
377 }
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
378
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
379 #else
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
380 /* Override the system's mbrtowc() function. */
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
381
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
382 # undef mbrtowc
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
383
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
384 size_t
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
385 rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
386 {
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
387 size_t ret;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
388 wchar_t wc;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
389
17660
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
390 # if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
391 if (s == NULL)
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
392 {
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
393 pwc = NULL;
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
394 s = "";
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
395 n = 1;
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
396 }
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
397 # endif
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
398
17660
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
399 # if MBRTOWC_EMPTY_INPUT_BUG
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
400 if (n == 0)
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
401 return (size_t) -2;
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
402 # endif
ea9dc06bfca8 mbrlen, mbrtowc: fix bug with empty input
Paul Eggert <eggert@cs.ucla.edu>
parents: 17576
diff changeset
403
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
404 if (! pwc)
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
405 pwc = &wc;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
406
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
407 # if MBRTOWC_RETVAL_BUG
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
408 {
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
409 static mbstate_t internal_state;
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
410
14561
ed6716f98fb1 maint: change "can not" to "cannot"
Jim Meyering <meyering@redhat.com>
parents: 14374
diff changeset
411 /* Override mbrtowc's internal state. We cannot call mbsinit() on the
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
412 hidden internal state, but we can call it on our variable. */
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
413 if (ps == NULL)
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
414 ps = &internal_state;
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
415
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
416 if (!mbsinit (ps))
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
417 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
418 /* Parse the rest of the multibyte character byte for byte. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
419 size_t count = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
420 for (; n > 0; s++, n--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
421 {
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
422 ret = mbrtowc (&wc, s, 1, ps);
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
423
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
424 if (ret == (size_t)(-1))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
425 return (size_t)(-1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
426 count++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
427 if (ret != (size_t)(-2))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
428 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
429 /* The multibyte character has been completed. */
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
430 *pwc = wc;
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
431 return (wc == 0 ? 0 : count);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
432 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
433 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11211
diff changeset
434 return (size_t)(-2);
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
435 }
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
436 }
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
437 # endif
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
438
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
439 ret = mbrtowc (pwc, s, n, ps);
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
440
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
441 # if MBRTOWC_NUL_RETVAL_BUG
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
442 if (ret < (size_t) -2 && !*pwc)
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
443 return 0;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
444 # endif
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
445
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
446 # if C_LOCALE_MAYBE_EILSEQ
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
447 if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
448 {
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
449 unsigned char uc = *s;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
450 *pwc = uc;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
451 return 1;
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
452 }
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
453 # endif
14042
1a75c9206d28 mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents: 13885
diff changeset
454
18292
24fde31e764d mbrtowc: work around glibc bug#19932
Paul Eggert <eggert@penguin.cs.ucla.edu>
parents: 18189
diff changeset
455 return ret;
10924
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
456 }
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
457
6f547b3710c7 Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents: 10909
diff changeset
458 #endif