Mercurial > gnulib
annotate lib/duplocale.c @ 40190:ef116535bf1a
relocatable-prog: Use $ORIGIN trick on more platforms.
* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Use $ORIGIN trick also on
FreeBSD >= 7.3, DragonFly >= 3.0, NetBSD >= 8.0, OpenBSD >= 5.4,
Solaris >= 10, Haiku. But don't use it on Android.
* build-aux/reloc-ldflags: Allow the use of the $ORIGIN trick also on
Hurd, FreeBSD, DragonFly, NetBSD, OpenBSD, Solaris, Haiku.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Wed, 20 Feb 2019 02:39:52 +0100 |
parents | b06060465f09 |
children |
rev | line source |
---|---|
12342 | 1 /* Duplicate a locale object. |
40057
b06060465f09
maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents:
19484
diff
changeset
|
2 Copyright (C) 2009-2019 Free Software Foundation, Inc. |
12342 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
19190 | 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
12342 | 16 |
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 /* Specification. */ | |
22 #include <locale.h> | |
23 | |
24 #include <errno.h> | |
25 #include <string.h> | |
26 | |
27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) | |
28 | |
29 #undef duplocale | |
30 | |
31 locale_t | |
32 rpl_duplocale (locale_t locale) | |
33 { | |
34 /* Work around crash in the duplocale function in glibc < 2.12. | |
19192
d86e08b1f555
all: Replace many more http URLs by https URLs. Update stale URLs.
Bruno Haible <bruno@clisp.org>
parents:
19190
diff
changeset
|
35 See <https://sourceware.org/bugzilla/show_bug.cgi?id=10969>. |
13509
a7655f9a621f
duplocale: Work around AIX 7.1 bug.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
36 Also, on AIX 7.1, duplocale(LC_GLOBAL_LOCALE) returns (locale_t)0 with |
19056
a3364f444fbc
duplocale: Work around NetBSD 7.0 bug.
Bruno Haible <bruno@clisp.org>
parents:
18626
diff
changeset
|
37 errno set to EINVAL. |
a3364f444fbc
duplocale: Work around NetBSD 7.0 bug.
Bruno Haible <bruno@clisp.org>
parents:
18626
diff
changeset
|
38 Also, on NetBSD 7.0, duplocale(LC_GLOBAL_LOCALE) returns a locale that |
a3364f444fbc
duplocale: Work around NetBSD 7.0 bug.
Bruno Haible <bruno@clisp.org>
parents:
18626
diff
changeset
|
39 corresponds to the C locale. */ |
12342 | 40 if (locale == LC_GLOBAL_LOCALE) |
41 { | |
42 /* Create a copy of the locale by fetching the name of each locale | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
43 category, starting with LC_CTYPE. */ |
12440 | 44 static struct { int cat; int mask; } const categories[] = |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
45 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
46 { LC_NUMERIC, LC_NUMERIC_MASK }, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
47 { LC_TIME, LC_TIME_MASK }, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
48 { LC_COLLATE, LC_COLLATE_MASK }, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
49 { LC_MONETARY, LC_MONETARY_MASK }, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
50 { LC_MESSAGES, LC_MESSAGES_MASK } |
12342 | 51 #ifdef LC_PAPER |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
52 , { LC_PAPER, LC_PAPER_MASK } |
12342 | 53 #endif |
54 #ifdef LC_NAME | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
55 , { LC_NAME, LC_NAME_MASK } |
12342 | 56 #endif |
57 #ifdef LC_ADDRESS | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
58 , { LC_ADDRESS, LC_ADDRESS_MASK } |
12342 | 59 #endif |
60 #ifdef LC_TELEPHONE | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
61 , { LC_TELEPHONE, LC_TELEPHONE_MASK } |
12342 | 62 #endif |
63 #ifdef LC_MEASUREMENT | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
64 , { LC_MEASUREMENT, LC_MEASUREMENT_MASK } |
12342 | 65 #endif |
66 #ifdef LC_IDENTIFICATION | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
67 , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK } |
12342 | 68 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
69 }; |
12345
97d443c1572f
duplocale: Add support for glibc 2.3.x.
Bruno Haible <bruno@clisp.org>
parents:
12342
diff
changeset
|
70 const char *base_name; |
97d443c1572f
duplocale: Add support for glibc 2.3.x.
Bruno Haible <bruno@clisp.org>
parents:
12342
diff
changeset
|
71 locale_t base_copy; |
12342 | 72 unsigned int i; |
73 | |
12347 | 74 base_name = setlocale (LC_CTYPE, NULL); |
12345
97d443c1572f
duplocale: Add support for glibc 2.3.x.
Bruno Haible <bruno@clisp.org>
parents:
12342
diff
changeset
|
75 base_copy = newlocale (LC_ALL_MASK, base_name, NULL); |
12342 | 76 if (base_copy == NULL) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
77 return NULL; |
12342 | 78 |
79 for (i = 0; i < SIZEOF (categories); i++) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
80 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
81 int category = categories[i].cat; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
82 int category_mask = categories[i].mask; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
83 const char *name = setlocale (category, NULL); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
84 if (strcmp (name, base_name) != 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
85 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
86 locale_t copy = newlocale (category_mask, name, base_copy); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
87 if (copy == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
88 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
89 int saved_errno = errno; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
90 freelocale (base_copy); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
91 errno = saved_errno; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
92 return NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
93 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
94 /* No need to call freelocale (base_copy) if copy != base_copy; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
95 the newlocale function already takes care of doing it. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
96 base_copy = copy; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
97 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12347
diff
changeset
|
98 } |
12342 | 99 |
100 return base_copy; | |
101 } | |
102 | |
103 return duplocale (locale); | |
104 } |