Mercurial > hg > octave-shane > gnulib-hg
annotate lib/wcsxfrm-impl.h @ 17480:f40b3156a43e
selinux-at: omit unnecessary include
* lib/selinux-at.c: Don't include dosname.h; not needed, since
this source file doesn't use its macros, and subsidiary files that
use the macros already include it.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Fri, 23 Aug 2013 13:53:46 -0700 |
parents | e542fd46ad6f |
children | 344018b6e5d7 |
rev | line source |
---|---|
14294 | 1 /* Transform wide string for comparison using the current locale. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16201
diff
changeset
|
2 Copyright (C) 2011-2013 Free Software Foundation, Inc. |
14294 | 3 Written by Bruno Haible <bruno@clisp.org>, 2011. |
4 | |
5 This program is free software: you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 3 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | |
18 size_t | |
19 wcsxfrm (wchar_t *s1, const wchar_t *s2, size_t n) | |
20 { | |
21 char mbbuf2[1024]; | |
22 char *mbs2; | |
23 | |
24 { | |
25 int saved_errno = errno; | |
26 size_t result; | |
27 | |
28 /* Convert s2 to a multibyte string, trying to avoid malloc(). */ | |
29 { | |
30 size_t ret; | |
31 | |
32 ret = wcstombs (mbbuf2, s2, sizeof (mbbuf2)); | |
33 if (ret == (size_t)-1) | |
34 goto failed; | |
35 if (ret < sizeof (mbbuf2)) | |
36 mbs2 = mbbuf2; | |
37 else | |
38 { | |
39 size_t need = wcstombs (NULL, s2, 0); | |
40 if (need == (size_t)-1) | |
41 goto failed; | |
42 mbs2 = (char *) malloc (need + 1); | |
43 if (mbs2 == NULL) | |
44 goto out_of_memory; | |
45 ret = wcstombs (mbs2, s2, need + 1); | |
46 if (ret != need) | |
47 abort (); | |
48 } | |
49 } | |
50 | |
51 /* Transform the multibyte string. */ | |
52 errno = 0; | |
53 result = strxfrm ((char *)s1, mbs2, n); | |
54 if (errno != 0) | |
55 { | |
56 /* An error occurred. */ | |
57 if (mbs2 != mbbuf2) | |
58 { | |
59 saved_errno = errno; | |
60 free (mbs2); | |
61 errno = saved_errno; | |
62 } | |
63 return 0; | |
64 } | |
65 | |
66 if (result < n) | |
67 { | |
68 /* Convert the result by mapping char[] -> wchar_t[]. | |
69 Since strcmp() compares the elements as 'unsigned char' values, | |
70 whereas wcscmp() compares the elements as 'wchar_t' values, we need | |
71 to map 1 'unsigned char' to 1 'wchar_t'. (We could also map 2 | |
72 consecutive 'unsigned char' values to 1 'wchar_t' value, but this is | |
73 not needed. */ | |
74 wchar_t *wcp = s1 + n; | |
75 char *cp = (char *)s1 + n; | |
76 | |
77 while (wcp > s1) | |
78 *--wcp = (wchar_t) (unsigned char) *--cp; | |
79 } | |
80 | |
81 if (mbs2 != mbbuf2) | |
82 free (mbs2); | |
83 | |
84 /* No error. */ | |
85 errno = saved_errno; | |
86 return result; | |
87 } | |
88 | |
89 out_of_memory: | |
90 errno = ENOMEM; | |
91 return 0; | |
92 | |
93 failed: | |
94 errno = EILSEQ; | |
95 return 0; | |
96 } |