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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
19204
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software; you can redistribute it and/or modify
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 3, or (at your option)
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 any later version.
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License along
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 with this program; if not, see <https://www.gnu.org/licenses/>. */
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 #include <config.h>
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 /* Specification. */
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include <monetary.h>
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
40216
02ed6264c100 strfmon_l: Fix -fsanitize=address finding.
Bruno Haible <bruno@clisp.org>
parents: 40057
diff changeset
22 #include <errno.h>
19204
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <locale.h>
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #undef strfmon_l
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 ssize_t
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 rpl_strfmon_l (char *s, size_t maxsize, locale_t locale, const char *format, ...)
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 {
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 /* Work around glibc 2.23 bug
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 <https://sourceware.org/bugzilla/show_bug.cgi?id=19633>. */
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 va_list argptr;
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 ssize_t result;
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 orig_locale = uselocale ((locale_t)0);
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 if (uselocale (locale) == (locale_t)0)
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 /* errno is set. */
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 return -1;
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
232 if (uselocale (orig_locale) == (locale_t)0)
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233 /* errno is set. */
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
234 return -1;
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
235
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
236 return result;
d0e723baf192 strfmon_l: New module.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
237 }