Mercurial > gnulib
annotate lib/wcsrtombs-impl.h @ 40196:e63f5d3edab5
relocatable-prog: Update documentation.
* doc/relocatable-maint.texi (Supporting Relocation): Update to match
the recent changes.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 24 Feb 2019 01:49:15 +0100 |
parents | b06060465f09 |
children |
rev | line source |
---|---|
14263
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
1 /* Convert wide string to string. |
40057
b06060465f09
maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents:
19484
diff
changeset
|
2 Copyright (C) 2008, 2010-2019 Free Software Foundation, Inc. |
14263
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
3 Written by Bruno Haible <bruno@clisp.org>, 2008. |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
4 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
6 it under the terms of the GNU General Public License as published by |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
8 (at your option) any later version. |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
9 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
10 This program is distributed in the hope that it will be useful, |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
13 GNU General Public License for more details. |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
14 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
15 You should have received a copy of the GNU General Public License |
19190 | 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
14263
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
17 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
18 size_t |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
19 wcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
20 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
21 if (ps == NULL) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
22 ps = &_gl_wcsrtombs_state; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
23 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
24 const wchar_t *src = *srcp; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
25 size_t cur_max = MB_CUR_MAX; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
26 char buf[64]; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
27 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
28 if (!(cur_max <= sizeof (buf))) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
29 abort (); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
30 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
31 if (dest != NULL) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
32 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
33 char *destptr = dest; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
34 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
35 for (; len > 0; src++) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
36 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
37 wchar_t wc = *src; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
38 size_t ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
39 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
40 if (ret == (size_t)(-1)) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
41 goto bad_input; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
42 if (!(ret <= cur_max)) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
43 abort (); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
44 if (len < ret) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
45 break; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
46 if (len < cur_max) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
47 memcpy (destptr, buf, ret); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
48 if (wc == 0) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
49 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
50 src = NULL; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
51 /* Here mbsinit (ps). */ |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
52 break; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
53 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
54 destptr += ret; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
55 len -= ret; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
56 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
57 *srcp = src; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
58 return destptr - dest; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
59 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
60 else |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
61 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
62 /* Ignore dest and len, don't store *srcp at the end, and |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
63 don't clobber *ps. */ |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
64 mbstate_t state = *ps; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
65 size_t totalcount = 0; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
66 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
67 for (;; src++) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
68 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
69 wchar_t wc = *src; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
70 size_t ret = wcrtomb (buf, wc, &state); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
71 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
72 if (ret == (size_t)(-1)) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
73 goto bad_input2; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
74 if (wc == 0) |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
75 { |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
76 /* Here mbsinit (&state). */ |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
77 break; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
78 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
79 totalcount += ret; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
80 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
81 return totalcount; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
82 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
83 |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
84 bad_input: |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
85 *srcp = src; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
86 bad_input2: |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
87 errno = EILSEQ; |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
88 return (size_t)(-1); |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
89 } |
72a370719412
wcsrtombs: Prepare for new module wwcsrtombs.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
90 } |