Mercurial > gnulib
annotate lib/strfmon_l.c @ 40231:9b3c79fdfe0b
strtod: fix clash with strtold
Problem reported for RHEL 5 by Jesse Caldwell (Bug#34817).
* lib/strtod.c (compute_minus_zero, minus_zero):
Simplify by remving the macro / external variable,
and having just a function. User changed. This avoids
the need for an external variable that might clash.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 11 Mar 2019 16:40:29 -0700 |
parents | 02ed6264c100 |
children |
rev | line source |
---|---|
19204 | 1 /* strfmon_l override. |
40057
b06060465f09
maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents:
19484
diff
changeset
|
2 Copyright (C) 2017-2019 Free Software Foundation, Inc. |
19204 | 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, or (at your option) | |
7 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 along | |
15 with this program; if not, see <https://www.gnu.org/licenses/>. */ | |
16 | |
17 #include <config.h> | |
18 | |
19 /* Specification. */ | |
20 #include <monetary.h> | |
21 | |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
22 #include <errno.h> |
19204 | 23 #include <locale.h> |
24 #include <stdarg.h> | |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
25 #include <stdbool.h> |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
26 #include <stdlib.h> |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
27 #include <string.h> |
19204 | 28 |
29 #undef strfmon_l | |
30 | |
31 /* This override can only support a limited number of arguments. */ | |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
32 #define MAX_ARGS 16 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
33 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
34 /* A parsed directive. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
35 typedef struct |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
36 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
37 bool needs_long_double; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
38 const char *conversion_ptr; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
39 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
40 directive_t; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
41 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
42 /* A parsed format string. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
43 typedef struct |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
44 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
45 size_t count; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
46 directive_t dir[MAX_ARGS]; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
47 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
48 directives_t; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
49 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
50 /* Parses a monetary format string. |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
51 Returns 0 and fills *DIRECTIVESP if valid. |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
52 Returns -1 if invalid. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
53 static int |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
54 fmon_parse (const char *format, directives_t *directivesp) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
55 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
56 size_t count = 0; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
57 const char *cp = format; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
58 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
59 while (*cp != '\0') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
60 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
61 if (*cp++ == '%') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
62 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
63 /* Parse flags. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
64 while (*cp == '=' || *cp == '^' || *cp == '+' || *cp == '(' |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
65 || *cp == '!' || *cp == '-') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
66 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
67 if (*cp == '=') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
68 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
69 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
70 if (*cp == '\0') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
71 return -1; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
72 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
73 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
74 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
75 /* Parse field width. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
76 while (*cp >= '0' && *cp <= '9') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
77 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
78 /* Parse left precision. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
79 if (*cp == '#') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
80 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
81 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
82 while (*cp >= '0' && *cp <= '9') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
83 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
84 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
85 /* Parse right precision. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
86 if (*cp == '.') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
87 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
88 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
89 while (*cp >= '0' && *cp <= '9') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
90 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
91 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
92 /* Now comes the conversion specifier. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
93 if (*cp != '%') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
94 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
95 if (count == MAX_ARGS) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
96 /* Too many arguments. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
97 return -1; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
98 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
99 /* glibc supports an 'L' modifier before the conversion specifier. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
100 if (*cp == 'L') |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
101 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
102 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
103 directivesp->dir[count].needs_long_double = true; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
104 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
105 else |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
106 directivesp->dir[count].needs_long_double = false; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
107 if (!(*cp == 'i' || *cp == 'n')) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
108 return -1; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
109 directivesp->dir[count].conversion_ptr = cp; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
110 count++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
111 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
112 cp++; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
113 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
114 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
115 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
116 directivesp->count = count; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
117 return 0; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
118 } |
19204 | 119 |
120 ssize_t | |
121 rpl_strfmon_l (char *s, size_t maxsize, locale_t locale, const char *format, ...) | |
122 { | |
123 /* Work around glibc 2.23 bug | |
124 <https://sourceware.org/bugzilla/show_bug.cgi?id=19633>. */ | |
125 va_list argptr; | |
126 locale_t orig_locale; | |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
127 directives_t directives; |
19204 | 128 ssize_t result; |
129 | |
130 orig_locale = uselocale ((locale_t)0); | |
131 | |
132 if (uselocale (locale) == (locale_t)0) | |
133 /* errno is set. */ | |
134 return -1; | |
135 | |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
136 /* The format string may consume 'double' or 'long double' arguments. |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
137 In order not to have to link with libffcall or libffi, convert all |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
138 arguments to 'long double', and use a modified format string that |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
139 requests 'long double' arguments. But since 'long double' arguments |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
140 are only supported on glibc, do so only if the original format string |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
141 consumes at least one 'long double' argument. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
142 if (fmon_parse (format, &directives) < 0) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
143 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
144 errno = EINVAL; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
145 result = -1; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
146 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
147 else |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
148 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
149 bool use_long_double; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
150 unsigned int i; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
151 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
152 use_long_double = false; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
153 for (i = 0; i < directives.count; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
154 if (directives.dir[i].needs_long_double) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
155 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
156 use_long_double = true; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
157 break; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
158 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
159 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
160 va_start (argptr, format); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
161 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
162 if (use_long_double) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
163 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
164 char *ld_format; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
165 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
166 /* Allocate room for the modified format string. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
167 ld_format = (char *) malloc (strlen (format) + directives.count + 1); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
168 if (ld_format == NULL) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
169 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
170 errno = ENOMEM; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
171 result = -1; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
172 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
173 else |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
174 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
175 long double args[MAX_ARGS]; |
19204 | 176 |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
177 /* Create the modified format string. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
178 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
179 const char *p = format; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
180 char *dest = ld_format; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
181 for (i = 0; i < directives.count; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
182 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
183 const char *q = directives.dir[i].conversion_ptr; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
184 memcpy (dest, p, q - p); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
185 dest += q - p; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
186 if (!directives.dir[i].needs_long_double) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
187 *dest++ = 'L'; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
188 p = q; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
189 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
190 strcpy (dest, p); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
191 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
192 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
193 /* Set up arguments array. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
194 for (i = 0; i < directives.count; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
195 args[i] = (directives.dir[i].needs_long_double |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
196 ? va_arg (argptr, long double) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
197 : (long double) va_arg (argptr, double)); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
198 /* Avoid uninitialized memory references. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
199 for (; i < MAX_ARGS; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
200 args[i] = 0.0L; |
19204 | 201 |
40216
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
202 result = strfmon_l (s, maxsize, locale, ld_format, |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
203 args[0], args[1], args[2], args[3], args[4], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
204 args[5], args[6], args[7], args[8], args[9], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
205 args[10], args[11], args[12], args[13], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
206 args[14], args[15]); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
207 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
208 free (ld_format); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
209 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
210 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
211 else |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
212 { |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
213 double args[MAX_ARGS]; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
214 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
215 /* Set up arguments array. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
216 for (i = 0; i < directives.count; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
217 args[i] = va_arg (argptr, double); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
218 /* Avoid uninitialized memory references. */ |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
219 for (; i < MAX_ARGS; i++) |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
220 args[i] = 0.0; |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
221 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
222 result = strfmon_l (s, maxsize, locale, format, |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
223 args[0], args[1], args[2], args[3], args[4], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
224 args[5], args[6], args[7], args[8], args[9], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
225 args[10], args[11], args[12], args[13], args[14], |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
226 args[15]); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
227 } |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
228 |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
229 va_end (argptr); |
02ed6264c100
strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents:
40057
diff
changeset
|
230 } |
19204 | 231 |
232 if (uselocale (orig_locale) == (locale_t)0) | |
233 /* errno is set. */ | |
234 return -1; | |
235 | |
236 return result; | |
237 } |