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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12342
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 (at your option) any later version.
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 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: 19056
diff changeset
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
12342
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #include <config.h>
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 /* Specification. */
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <locale.h>
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <errno.h>
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <string.h>
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #undef duplocale
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 locale_t
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 rpl_duplocale (locale_t locale)
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 {
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 if (locale == LC_GLOBAL_LOCALE)
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 {
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
7845453bc803 duplocale: Tweak.
Bruno Haible <bruno@clisp.org>
parents: 12421
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 #endif
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 #endif
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 #endif
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 #endif
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 #endif
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 unsigned int i;
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73
12347
8fcfa42d797d duplocale: Fix logic bug.
Bruno Haible <bruno@clisp.org>
parents: 12345
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 return base_copy;
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 }
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 return duplocale (locale);
f214e6acb33b New module 'duplocale'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 }