annotate Python/pystrtod.c @ 49955:878d40468c4e legacy-trunk

Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
author Vinay Sajip <vinay_sajip@yahoo.co.uk>
date Wed, 03 Dec 2008 23:22:58 +0000
parents 40db45bfc0f2
children f7eccf769c1a c5e0d9beebf9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 /* -*- Mode: C; c-file-style: "python" -*- */
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3 #include <Python.h>
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
4 #include <locale.h>
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
5
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
6 /* ascii character tests (as opposed to locale tests) */
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
7 #define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
8 (c) == '\r' || (c) == '\t' || (c) == '\v')
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
9 #define ISDIGIT(c) ((c) >= '0' && (c) <= '9')
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
10
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
11
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
12 /**
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
13 * PyOS_ascii_strtod:
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
14 * @nptr: the string to convert to a numeric value.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
15 * @endptr: if non-%NULL, it returns the character after
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
16 * the last character used in the conversion.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
17 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
18 * Converts a string to a #gdouble value.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
19 * This function behaves like the standard strtod() function
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
20 * does in the C locale. It does this without actually
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
21 * changing the current locale, since that would not be
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
22 * thread-safe.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
23 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
24 * This function is typically used when reading configuration
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
25 * files or other non-user input that should be locale independent.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
26 * To handle input from the user you should normally use the
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
27 * locale-sensitive system strtod() function.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
28 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
29 * If the correct value would cause overflow, plus or minus %HUGE_VAL
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
30 * is returned (according to the sign of the value), and %ERANGE is
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
31 * stored in %errno. If the correct value would cause underflow,
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
32 * zero is returned and %ERANGE is stored in %errno.
38480
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
33 * If memory allocation fails, %ENOMEM is stored in %errno.
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
34 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
35 * This function resets %errno before calling strtod() so that
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
36 * you can reliably detect overflow and underflow.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
37 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
38 * Return value: the #gdouble value.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
39 **/
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
40 double
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
41 PyOS_ascii_strtod(const char *nptr, char **endptr)
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
42 {
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
43 char *fail_pos;
36080
10440bcfa061 Fix compiler warnings
Neal Norwitz <nnorwitz@gmail.com>
parents: 36077
diff changeset
44 double val = -1.0;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
45 struct lconv *locale_data;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
46 const char *decimal_point;
36230
ded4a497eb76 Fix icc warnings: strlen() returns size_t
Neal Norwitz <nnorwitz@gmail.com>
parents: 36080
diff changeset
47 size_t decimal_point_len;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
48 const char *p, *decimal_point_pos;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
49 const char *end = NULL; /* Silence gcc */
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
50 const char *digits_pos = NULL;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
51 int negate = 0;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
52
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
53 assert(nptr != NULL);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
54
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
55 fail_pos = NULL;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
56
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
57 locale_data = localeconv();
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
58 decimal_point = locale_data->decimal_point;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
59 decimal_point_len = strlen(decimal_point);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
60
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
61 assert(decimal_point_len != 0);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
63 decimal_point_pos = NULL;
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
64
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
65 /* We process any leading whitespace and the optional sign manually,
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
66 then pass the remainder to the system strtod. This ensures that
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
67 the result of an underflow has the correct sign. (bug #1725) */
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
68
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
69 p = nptr;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
70 /* Skip leading space */
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
71 while (ISSPACE(*p))
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
72 p++;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
73
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
74 /* Process leading sign, if present */
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
75 if (*p == '-') {
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
76 negate = 1;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
77 p++;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
78 } else if (*p == '+') {
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
79 p++;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
80 }
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
81
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
82 /* What's left should begin with a digit, a decimal point, or one of
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
83 the letters i, I, n, N. It should not begin with 0x or 0X */
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
84 if ((!ISDIGIT(*p) &&
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
85 *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N')
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
86 ||
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
87 (*p == '0' && (p[1] == 'x' || p[1] == 'X')))
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
88 {
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
89 if (endptr)
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
90 *endptr = (char*)nptr;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
91 errno = EINVAL;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
92 return val;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
93 }
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
94 digits_pos = p;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
95
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
96 if (decimal_point[0] != '.' ||
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
97 decimal_point[1] != 0)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
98 {
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
99 while (ISDIGIT(*p))
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
100 p++;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
101
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
102 if (*p == '.')
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
103 {
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
104 decimal_point_pos = p++;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
105
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
106 while (ISDIGIT(*p))
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
107 p++;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
108
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
109 if (*p == 'e' || *p == 'E')
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
110 p++;
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
111 if (*p == '+' || *p == '-')
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
112 p++;
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
113 while (ISDIGIT(*p))
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
114 p++;
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
115 end = p;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
116 }
38989
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
117 else if (strncmp(p, decimal_point, decimal_point_len) == 0)
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
118 {
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
119 /* Python bug #1417699 */
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
120 if (endptr)
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
121 *endptr = (char*)nptr;
38989
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
122 errno = EINVAL;
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
123 return val;
0e8a94ba2106 Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents: 38481
diff changeset
124 }
45786
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
125 /* For the other cases, we need not convert the decimal
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
126 point */
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
127 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
128
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
129 /* Set errno to zero, so that we can distinguish zero results
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
130 and underflows */
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
131 errno = 0;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
132
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
133 if (decimal_point_pos)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
134 {
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
135 char *copy, *c;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
136
45786
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
137 /* We need to convert the '.' to the locale specific decimal
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
138 point */
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
139 copy = (char *)PyMem_MALLOC(end - digits_pos +
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
140 1 + decimal_point_len);
38480
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
141 if (copy == NULL) {
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
142 if (endptr)
38481
3d1a99b39fca Fix compiler warning.
Georg Brandl <georg@python.org>
parents: 38480
diff changeset
143 *endptr = (char *)nptr;
38480
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
144 errno = ENOMEM;
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
145 return val;
9b001ebeaa5e Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents: 38320
diff changeset
146 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
147
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
148 c = copy;
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
149 memcpy(c, digits_pos, decimal_point_pos - digits_pos);
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
150 c += decimal_point_pos - digits_pos;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
151 memcpy(c, decimal_point, decimal_point_len);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
152 c += decimal_point_len;
45786
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
153 memcpy(c, decimal_point_pos + 1,
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
154 end - (decimal_point_pos + 1));
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
155 c += end - (decimal_point_pos + 1);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
156 *c = 0;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
157
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
158 val = strtod(copy, &fail_pos);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
159
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
160 if (fail_pos)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
161 {
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
162 if (fail_pos > decimal_point_pos)
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
163 fail_pos = (char *)digits_pos +
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
164 (fail_pos - copy) -
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
165 (decimal_point_len - 1);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
166 else
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
167 fail_pos = (char *)digits_pos +
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
168 (fail_pos - copy);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
169 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
170
38320
3d477d158401 Swap out bare malloc()/free() use for PyMem_MALLOC()/PyMem_FREE() .
Brett Cannon <bcannon@gmail.com>
parents: 37607
diff changeset
171 PyMem_FREE(copy);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
172
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
173 }
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
174 else {
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
175 val = strtod(digits_pos, &fail_pos);
36077
3b90258fec9f Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents: 32305
diff changeset
176 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
177
44482
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
178 if (fail_pos == digits_pos)
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
179 fail_pos = (char *)nptr;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
180
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
181 if (negate && fail_pos != nptr)
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
182 val = -val;
3fcaf6cc306d Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents: 38989
diff changeset
183
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
184 if (endptr)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
185 *endptr = fail_pos;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
186
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
187 return val;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
188 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
189
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
190 /* Given a string that may have a decimal point in the current
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
191 locale, change it back to a dot. Since the string cannot get
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
192 longer, no need for a maximum buffer size parameter. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
193 Py_LOCAL_INLINE(void)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
194 change_decimal_from_locale_to_dot(char* buffer)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
195 {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
196 struct lconv *locale_data = localeconv();
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
197 const char *decimal_point = locale_data->decimal_point;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
198
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
199 if (decimal_point[0] != '.' || decimal_point[1] != 0) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
200 size_t decimal_point_len = strlen(decimal_point);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
201
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
202 if (*buffer == '+' || *buffer == '-')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
203 buffer++;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
204 while (isdigit(Py_CHARMASK(*buffer)))
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
205 buffer++;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
206 if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
207 *buffer = '.';
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
208 buffer++;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
209 if (decimal_point_len > 1) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
210 /* buffer needs to get smaller */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
211 size_t rest_len = strlen(buffer +
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
212 (decimal_point_len - 1));
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
213 memmove(buffer,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
214 buffer + (decimal_point_len - 1),
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
215 rest_len);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
216 buffer[rest_len] = 0;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
217 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
218 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
219 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
220 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
221
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
222
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
223 /* From the C99 standard, section 7.19.6:
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
224 The exponent always contains at least two digits, and only as many more digits
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
225 as necessary to represent the exponent.
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
226 */
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
227 #define MIN_EXPONENT_DIGITS 2
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
228
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
229 /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
230 in length. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
231 Py_LOCAL_INLINE(void)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
232 ensure_minumim_exponent_length(char* buffer, size_t buf_size)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
233 {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
234 char *p = strpbrk(buffer, "eE");
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
235 if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
236 char *start = p + 2;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
237 int exponent_digit_cnt = 0;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
238 int leading_zero_cnt = 0;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
239 int in_leading_zeros = 1;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
240 int significant_digit_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
241
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
242 /* Skip over the exponent and the sign. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
243 p += 2;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
244
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
245 /* Find the end of the exponent, keeping track of leading
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
246 zeros. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
247 while (*p && isdigit(Py_CHARMASK(*p))) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
248 if (in_leading_zeros && *p == '0')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
249 ++leading_zero_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
250 if (*p != '0')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
251 in_leading_zeros = 0;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
252 ++p;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
253 ++exponent_digit_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
254 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
255
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
256 significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
257 if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
258 /* If there are 2 exactly digits, we're done,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
259 regardless of what they contain */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
260 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
261 else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
262 int extra_zeros_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
263
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
264 /* There are more than 2 digits in the exponent. See
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
265 if we can delete some of the leading zeros */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
266 if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
267 significant_digit_cnt = MIN_EXPONENT_DIGITS;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
268 extra_zeros_cnt = exponent_digit_cnt -
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
269 significant_digit_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
270
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
271 /* Delete extra_zeros_cnt worth of characters from the
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
272 front of the exponent */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
273 assert(extra_zeros_cnt >= 0);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
274
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
275 /* Add one to significant_digit_cnt to copy the
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
276 trailing 0 byte, thus setting the length */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
277 memmove(start,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
278 start + extra_zeros_cnt,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
279 significant_digit_cnt + 1);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
280 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
281 else {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
282 /* If there are fewer than 2 digits, add zeros
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
283 until there are 2, if there's enough room */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
284 int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
285 if (start + zeros + exponent_digit_cnt + 1
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
286 < buffer + buf_size) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
287 memmove(start + zeros, start,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
288 exponent_digit_cnt + 1);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
289 memset(start, '0', zeros);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
290 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
291 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
292 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
293 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
294
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
295 /* Ensure that buffer has a decimal point in it. The decimal point
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
296 will not be in the current locale, it will always be '.' */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
297 Py_LOCAL_INLINE(void)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
298 ensure_decimal_point(char* buffer, size_t buf_size)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
299 {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
300 int insert_count = 0;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
301 char* chars_to_insert;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
302
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
303 /* search for the first non-digit character */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
304 char *p = buffer;
48021
40db45bfc0f2 Fix issue 3411: default float format spec fails on negative numbers.
Eric Smith <eric@trueblade.com>
parents: 47815
diff changeset
305 if (*p == '-' || *p == '+')
40db45bfc0f2 Fix issue 3411: default float format spec fails on negative numbers.
Eric Smith <eric@trueblade.com>
parents: 47815
diff changeset
306 /* Skip leading sign, if present. I think this could only
40db45bfc0f2 Fix issue 3411: default float format spec fails on negative numbers.
Eric Smith <eric@trueblade.com>
parents: 47815
diff changeset
307 ever be '-', but it can't hurt to check for both. */
40db45bfc0f2 Fix issue 3411: default float format spec fails on negative numbers.
Eric Smith <eric@trueblade.com>
parents: 47815
diff changeset
308 ++p;
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
309 while (*p && isdigit(Py_CHARMASK(*p)))
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
310 ++p;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
311
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
312 if (*p == '.') {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
313 if (isdigit(Py_CHARMASK(*(p+1)))) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
314 /* Nothing to do, we already have a decimal
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
315 point and a digit after it */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
316 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
317 else {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
318 /* We have a decimal point, but no following
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
319 digit. Insert a zero after the decimal. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
320 ++p;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
321 chars_to_insert = "0";
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
322 insert_count = 1;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
323 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
324 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
325 else {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
326 chars_to_insert = ".0";
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
327 insert_count = 2;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
328 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
329 if (insert_count) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
330 size_t buf_len = strlen(buffer);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
331 if (buf_len + insert_count + 1 >= buf_size) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
332 /* If there is not enough room in the buffer
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
333 for the additional text, just skip it. It's
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
334 not worth generating an error over. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
335 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
336 else {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
337 memmove(p + insert_count, p,
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
338 buffer + strlen(buffer) - p + 1);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
339 memcpy(p, chars_to_insert, insert_count);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
340 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
341 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
342 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
343
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
344 /* Add the locale specific grouping characters to buffer. Note
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
345 that any decimal point (if it's present) in buffer is already
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
346 locale-specific. Return 0 on error, else 1. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
347 Py_LOCAL_INLINE(int)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
348 add_thousands_grouping(char* buffer, size_t buf_size)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
349 {
46898
206700d749f0 Addresses issue 2802: 'n' formatting for integers.
Eric Smith <eric@trueblade.com>
parents: 46600
diff changeset
350 Py_ssize_t len = strlen(buffer);
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
351 struct lconv *locale_data = localeconv();
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
352 const char *decimal_point = locale_data->decimal_point;
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
353
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
354 /* Find the decimal point, if any. We're only concerned
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
355 about the characters to the left of the decimal when
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
356 adding grouping. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
357 char *p = strstr(buffer, decimal_point);
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
358 if (!p) {
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
359 /* No decimal, use the entire string. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
360
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
361 /* If any exponent, adjust p. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
362 p = strpbrk(buffer, "eE");
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
363 if (!p)
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
364 /* No exponent and no decimal. Use the entire
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
365 string. */
46898
206700d749f0 Addresses issue 2802: 'n' formatting for integers.
Eric Smith <eric@trueblade.com>
parents: 46600
diff changeset
366 p = buffer + len;
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
367 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
368 /* At this point, p points just past the right-most character we
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
369 want to format. We need to add the grouping string for the
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
370 characters between buffer and p. */
47815
752e1abaf15a Modified interface to _Py_[String|Unicode]InsertThousandsGrouping, in anticipation of fixing issue 3140.
Eric Smith <eric@trueblade.com>
parents: 47527
diff changeset
371 return _PyString_InsertThousandsGrouping(buffer, len, p-buffer,
46898
206700d749f0 Addresses issue 2802: 'n' formatting for integers.
Eric Smith <eric@trueblade.com>
parents: 46600
diff changeset
372 buf_size, NULL, 1);
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
373 }
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
374
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
375 /* see FORMATBUFLEN in unicodeobject.c */
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
376 #define FLOAT_FORMATBUFLEN 120
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
377
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
378 /**
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
379 * PyOS_ascii_formatd:
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
380 * @buffer: A buffer to place the resulting string in
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
381 * @buf_size: The length of the buffer.
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
382 * @format: The printf()-style format to use for the
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
383 * code to use for converting.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
384 * @d: The #gdouble to convert
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
385 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
386 * Converts a #gdouble to a string, using the '.' as
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
387 * decimal point. To format the number you pass in
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
388 * a printf()-style format string. Allowed conversion
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
389 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'n'.
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
390 *
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
391 * 'n' is the same as 'g', except it uses the current locale.
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
392 * 'Z' is the same as 'g', except it always has a decimal and
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
393 * at least one digit after the decimal.
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
394 *
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
395 * Return value: The pointer to the buffer with the converted string.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
396 **/
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
397 char *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
398 PyOS_ascii_formatd(char *buffer,
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
399 size_t buf_size,
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
400 const char *format,
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
401 double d)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
402 {
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
403 char format_char;
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
404 size_t format_len = strlen(format);
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
405
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
406 /* For type 'n', we need to make a copy of the format string, because
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
407 we're going to modify 'n' -> 'g', and format is const char*, so we
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
408 can't modify it directly. FLOAT_FORMATBUFLEN should be longer than
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
409 we ever need this to be. There's an upcoming check to ensure it's
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
410 big enough. */
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
411 /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
412 also with at least one character past the decimal. */
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
413 char tmp_format[FLOAT_FORMATBUFLEN];
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
414
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
415 /* The last character in the format string must be the format char */
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
416 format_char = format[format_len - 1];
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
417
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
418 if (format[0] != '%')
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
419 return NULL;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
420
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
421 /* I'm not sure why this test is here. It's ensuring that the format
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
422 string after the first character doesn't have a single quote, a
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
423 lowercase l, or a percent. This is the reverse of the commented-out
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
424 test about 10 lines ago. */
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
425 if (strpbrk(format + 1, "'l%"))
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
426 return NULL;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
427
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
428 /* Also curious about this function is that it accepts format strings
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
429 like "%xg", which are invalid for floats. In general, the
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
430 interface to this function is not very good, but changing it is
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
431 difficult because it's a public API. */
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
432
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
433 if (!(format_char == 'e' || format_char == 'E' ||
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
434 format_char == 'f' || format_char == 'F' ||
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
435 format_char == 'g' || format_char == 'G' ||
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
436 format_char == 'n' || format_char == 'Z'))
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
437 return NULL;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
438
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
439 /* Map 'n' or 'Z' format_char to 'g', by copying the format string and
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
440 replacing the final char with a 'g' */
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
441 if (format_char == 'n' || format_char == 'Z') {
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
442 if (format_len + 1 >= sizeof(tmp_format)) {
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
443 /* The format won't fit in our copy. Error out. In
45786
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
444 practice, this will never happen and will be
16732db00822 Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents: 45785
diff changeset
445 detected by returning NULL */
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
446 return NULL;
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
447 }
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
448 strcpy(tmp_format, format);
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
449 tmp_format[format_len - 1] = 'g';
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
450 format = tmp_format;
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
451 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
452
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
453
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
454 /* Have PyOS_snprintf do the hard work */
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
455 PyOS_snprintf(buffer, buf_size, format, d);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
456
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
457 /* Do various fixups on the return string */
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
458
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
459 /* Get the current locale, and find the decimal point string.
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
460 Convert that string back to a dot. Do not do this if using the
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
461 'n' (number) format code, since we want to keep the localized
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
462 decimal point in that case. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
463 if (format_char != 'n')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
464 change_decimal_from_locale_to_dot(buffer);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
465
45403
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
466 /* If an exponent exists, ensure that the exponent is at least
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
467 MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
468 for the extra zeros. Also, if there are more than
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
469 MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
0ea236a71d77 Trim leading zeros from a floating point exponent, per C99. See issue 1600. As far as I know, this only affects Windows. Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
Eric Smith <eric@trueblade.com>
parents: 44482
diff changeset
470 back to MIN_EXPONENT_DIGITS */
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
471 ensure_minumim_exponent_length(buffer, buf_size);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
472
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
473 /* If format_char is 'Z', make sure we have at least one character
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
474 after the decimal point (and make sure we have a decimal point). */
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
475 if (format_char == 'Z')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
476 ensure_decimal_point(buffer, buf_size);
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
477
46600
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
478 /* If format_char is 'n', add the thousands grouping. */
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
479 if (format_char == 'n')
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
480 if (!add_thousands_grouping(buffer, buf_size))
37d645b01523 Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents: 45786
diff changeset
481 return NULL;
45785
4d29127f3fa0 Issue 2264: empty float presentation type needs to have at least one digit past the decimal point.
Eric Smith <eric@trueblade.com>
parents: 45403
diff changeset
482
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
483 return buffer;
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
484 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
485
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
486 double
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
487 PyOS_ascii_atof(const char *nptr)
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
488 {
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
489 return PyOS_ascii_strtod(nptr, NULL);
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
490 }