Mercurial > cpython-lru_cache-weakref
annotate Python/pystrtod.c @ 55725:ec8d25e0500a legacy-trunk
#6677: mention "deleting" as an alias for removing files.
| author | Georg Brandl <georg@python.org> |
|---|---|
| date | Mon, 24 Aug 2009 17:24:27 +0000 |
| parents | 1d8f24d40c2c |
| children | 38fda3a42c0b |
| 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 /** |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
7 * PyOS_ascii_strtod: |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
8 * @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
|
9 * @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
|
10 * 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
|
11 * |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
12 * 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
|
13 * 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
|
14 * 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
|
15 * 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
|
16 * thread-safe. |
|
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 * 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
|
19 * 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
|
20 * 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
|
21 * locale-sensitive system strtod() function. |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
22 * |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
23 * 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
|
24 * 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
|
25 * 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
|
26 * 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
|
27 * 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
|
28 * |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
29 * 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
|
30 * 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
|
31 * |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
32 * Return value: the #gdouble value. |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
33 **/ |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
34 |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
35 /* |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
36 Use system strtod; since strtod is locale aware, we may |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
37 have to first fix the decimal separator. |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
38 |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
39 Note that unlike _Py_dg_strtod, the system strtod may not always give |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
40 correctly rounded results. |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
41 */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
42 |
|
53716
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
43 /* Case-insensitive string match used for nan and inf detection; t should be |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
44 lower-case. Returns 1 for a successful match, 0 otherwise. */ |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
45 |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
46 static int |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
47 case_insensitive_match(const char *s, const char *t) |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
48 { |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
49 while(*t && Py_TOLOWER(*s) == *t) { |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
50 s++; |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
51 t++; |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
52 } |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
53 return *t ? 0 : 1; |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
54 } |
|
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
55 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
56 double |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
57 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
|
58 { |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
59 char *fail_pos; |
| 36080 | 60 double val = -1.0; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
61 struct lconv *locale_data; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
62 const char *decimal_point; |
|
36230
ded4a497eb76
Fix icc warnings: strlen() returns size_t
Neal Norwitz <nnorwitz@gmail.com>
parents:
36080
diff
changeset
|
63 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
|
64 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
|
65 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
|
66 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
|
67 int negate = 0; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
68 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
69 assert(nptr != NULL); |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
70 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
71 fail_pos = NULL; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
72 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
73 locale_data = localeconv(); |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
74 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
|
75 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
|
76 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
77 assert(decimal_point_len != 0); |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
78 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
79 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
|
80 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
81 /* Set errno to zero, so that we can distinguish zero results |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
82 and underflows */ |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
83 errno = 0; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
84 |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
85 /* 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
|
86 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
|
87 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
|
88 |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
89 p = nptr; |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
90 /* Skip leading space */ |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
91 while (Py_ISSPACE(*p)) |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
92 p++; |
|
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 /* 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
|
95 if (*p == '-') { |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
96 negate = 1; |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
97 p++; |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
98 } |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
99 else if (*p == '+') { |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
100 p++; |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
101 } |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
102 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
103 /* Parse infinities and nans */ |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
104 if (*p == 'i' || *p == 'I') { |
|
53716
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
105 if (case_insensitive_match(p+1, "nf")) { |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
106 val = Py_HUGE_VAL; |
|
53716
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
107 if (case_insensitive_match(p+3, "inity")) |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
108 fail_pos = (char *)p+8; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
109 else |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
110 fail_pos = (char *)p+3; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
111 goto got_val; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
112 } |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
113 else |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
114 goto invalid_string; |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
115 } |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
116 #ifdef Py_NAN |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
117 if (*p == 'n' || *p == 'N') { |
|
53716
4f867f1494d5
Don't use PyOS_strnicmp for NaN and Inf detection: it's locale-aware.
Mark Dickinson <dickinsm@gmail.com>
parents:
53712
diff
changeset
|
118 if (case_insensitive_match(p+1, "an")) { |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
119 val = Py_NAN; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
120 fail_pos = (char *)p+3; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
121 goto got_val; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
122 } |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
123 else |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
124 goto invalid_string; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
125 } |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
126 #endif |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
127 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
128 /* Some platform strtods accept hex floats; Python shouldn't (at the |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
129 moment), so we check explicitly for strings starting with '0x'. */ |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
130 if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
131 goto invalid_string; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
132 |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
133 /* Check that what's left begins with a digit or decimal point */ |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
134 if (!Py_ISDIGIT(*p) && *p != '.') |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
135 goto invalid_string; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
136 |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
137 digits_pos = p; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
138 if (decimal_point[0] != '.' || |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
139 decimal_point[1] != 0) |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
140 { |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
141 /* Look for a '.' in the input; if present, it'll need to be |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
142 swapped for the current locale's decimal point before we |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
143 call strtod. On the other hand, if we find the current |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
144 locale's decimal point then the input is invalid. */ |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
145 while (Py_ISDIGIT(*p)) |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
146 p++; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
147 |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
148 if (*p == '.') |
|
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
149 { |
|
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
150 decimal_point_pos = p++; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
151 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
152 /* locate end of number */ |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
153 while (Py_ISDIGIT(*p)) |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
154 p++; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
155 |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
156 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
|
157 p++; |
|
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
158 if (*p == '+' || *p == '-') |
|
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
159 p++; |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
160 while (Py_ISDIGIT(*p)) |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
161 p++; |
|
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
162 end = p; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
163 } |
|
38989
0e8a94ba2106
Bug #1417699: Reject locale-specific decimal point in float()
Martin v. Löwis <martin@v.loewis.de>
parents:
38481
diff
changeset
|
164 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
|
165 /* Python bug #1417699 */ |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
166 goto invalid_string; |
|
45786
16732db00822
Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents:
45785
diff
changeset
|
167 /* For the other cases, we need not convert the decimal |
|
16732db00822
Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents:
45785
diff
changeset
|
168 point */ |
|
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 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
171 if (decimal_point_pos) { |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
172 char *copy, *c; |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
173 /* Create a copy of the input, with the '.' converted to the |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
174 locale-specific decimal point */ |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
175 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
|
176 1 + decimal_point_len); |
|
38480
9b001ebeaa5e
Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents:
38320
diff
changeset
|
177 if (copy == NULL) { |
|
9b001ebeaa5e
Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents:
38320
diff
changeset
|
178 if (endptr) |
| 38481 | 179 *endptr = (char *)nptr; |
|
38480
9b001ebeaa5e
Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents:
38320
diff
changeset
|
180 errno = ENOMEM; |
|
9b001ebeaa5e
Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents:
38320
diff
changeset
|
181 return val; |
|
9b001ebeaa5e
Handle PyMem_Malloc failure in pystrtod.c. Closes #1494671.
Georg Brandl <georg@python.org>
parents:
38320
diff
changeset
|
182 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
183 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
184 c = copy; |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
185 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
|
186 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
|
187 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
|
188 c += decimal_point_len; |
|
45786
16732db00822
Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents:
45785
diff
changeset
|
189 memcpy(c, decimal_point_pos + 1, |
|
16732db00822
Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents:
45785
diff
changeset
|
190 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
|
191 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
|
192 *c = 0; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
193 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
194 val = strtod(copy, &fail_pos); |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
195 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
196 if (fail_pos) |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
197 { |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
198 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
|
199 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
|
200 (fail_pos - copy) - |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
201 (decimal_point_len - 1); |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
202 else |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
203 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
|
204 (fail_pos - copy); |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
205 } |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
206 |
|
38320
3d477d158401
Swap out bare malloc()/free() use for PyMem_MALLOC()/PyMem_FREE() .
Brett Cannon <bcannon@gmail.com>
parents:
37607
diff
changeset
|
207 PyMem_FREE(copy); |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
208 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
209 } |
|
36077
3b90258fec9f
Get float() to be more portable across platforms. Disable hex strings.
Neal Norwitz <nnorwitz@gmail.com>
parents:
32305
diff
changeset
|
210 else { |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
211 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
|
212 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
213 |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
214 if (fail_pos == digits_pos) |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
215 goto invalid_string; |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
216 |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
217 got_val: |
|
44482
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
218 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
|
219 val = -val; |
|
3fcaf6cc306d
Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000
Guido van Rossum <guido@python.org>
parents:
38989
diff
changeset
|
220 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
221 if (endptr) |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
222 *endptr = fail_pos; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
223 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
224 return val; |
|
53470
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
225 |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
226 invalid_string: |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
227 if (endptr) |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
228 *endptr = (char*)nptr; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
229 errno = EINVAL; |
|
01c3363a357f
Backport r71967 changes from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents:
53442
diff
changeset
|
230 return -1.0; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
231 } |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
232 |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
233 double |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
234 PyOS_ascii_atof(const char *nptr) |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
235 { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
236 return PyOS_ascii_strtod(nptr, NULL); |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
237 } |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
238 |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
239 |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
240 /* 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
|
241 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
|
242 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
|
243 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
|
244 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
|
245 { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
246 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
|
247 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
|
248 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
249 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
|
250 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
|
251 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
252 if (*buffer == '+' || *buffer == '-') |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
253 buffer++; |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
254 while (Py_ISDIGIT(*buffer)) |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
255 buffer++; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
256 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
|
257 *buffer = '.'; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
258 buffer++; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
259 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
|
260 /* 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
|
261 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
|
262 (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
|
263 memmove(buffer, |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
264 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
|
265 rest_len); |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
266 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
|
267 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
268 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
269 } |
|
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 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
272 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
273 Py_LOCAL_INLINE(void) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
274 ensure_sign(char* buffer, size_t buf_size) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
275 { |
|
53555
d9b9422b409c
Silence warning on Windows.
Eric Smith <eric@trueblade.com>
parents:
53539
diff
changeset
|
276 size_t len; |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
277 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
278 if (buffer[0] == '-') |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
279 /* Already have a sign. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
280 return; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
281 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
282 /* Include the trailing 0 byte. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
283 len = strlen(buffer)+1; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
284 if (len >= buf_size+1) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
285 /* No room for the sign, don't do anything. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
286 return; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
287 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
288 memmove(buffer+1, buffer, len); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
289 buffer[0] = '+'; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
290 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
291 |
|
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
|
292 /* 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
|
293 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
|
294 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
|
295 */ |
|
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
|
296 #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
|
297 |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
298 /* 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
|
299 in length. */ |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
300 Py_LOCAL_INLINE(void) |
|
53477
bfb47bc1d051
Fix typo in function name
Mark Dickinson <dickinsm@gmail.com>
parents:
53470
diff
changeset
|
301 ensure_minimum_exponent_length(char* buffer, size_t buf_size) |
|
46600
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 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
|
304 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
|
305 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
|
306 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
|
307 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
|
308 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
|
309 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
|
310 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
311 /* 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
|
312 p += 2; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
313 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
314 /* 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
|
315 zeros. */ |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
316 while (*p && Py_ISDIGIT(*p)) { |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
317 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
|
318 ++leading_zero_cnt; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
319 if (*p != '0') |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
320 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
|
321 ++p; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
322 ++exponent_digit_cnt; |
|
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 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
|
326 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
|
327 /* 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
|
328 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
|
329 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
330 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
|
331 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
|
332 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
333 /* 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
|
334 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
|
335 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
|
336 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
|
337 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
|
338 significant_digit_cnt; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
339 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
340 /* 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
|
341 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
|
342 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
|
343 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
344 /* 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
|
345 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
|
346 memmove(start, |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
347 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
|
348 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
|
349 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
350 else { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
351 /* 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
|
352 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
|
353 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
|
354 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
|
355 < buffer + buf_size) { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
356 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
|
357 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
|
358 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
|
359 } |
|
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 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
362 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
363 |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
364 /* Remove trailing zeros after the decimal point from a numeric string; also |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
365 remove the decimal point if all digits following it are zero. The numeric |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
366 string must end in '\0', and should not have any leading or trailing |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
367 whitespace. Assumes that the decimal point is '.'. */ |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
368 Py_LOCAL_INLINE(void) |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
369 remove_trailing_zeros(char *buffer) |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
370 { |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
371 char *old_fraction_end, *new_fraction_end, *end, *p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
372 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
373 p = buffer; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
374 if (*p == '-' || *p == '+') |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
375 /* Skip leading sign, if present */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
376 ++p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
377 while (Py_ISDIGIT(*p)) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
378 ++p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
379 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
380 /* if there's no decimal point there's nothing to do */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
381 if (*p++ != '.') |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
382 return; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
383 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
384 /* scan any digits after the point */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
385 while (Py_ISDIGIT(*p)) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
386 ++p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
387 old_fraction_end = p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
388 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
389 /* scan up to ending '\0' */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
390 while (*p != '\0') |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
391 p++; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
392 /* +1 to make sure that we move the null byte as well */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
393 end = p+1; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
394 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
395 /* scan back from fraction_end, looking for removable zeros */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
396 p = old_fraction_end; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
397 while (*(p-1) == '0') |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
398 --p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
399 /* and remove point if we've got that far */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
400 if (*(p-1) == '.') |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
401 --p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
402 new_fraction_end = p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
403 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
404 memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
405 } |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
406 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
407 /* Ensure that buffer has a decimal point in it. The decimal point will not |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
408 be in the current locale, it will always be '.'. Don't add a decimal point |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
409 if an exponent is present. Also, convert to exponential notation where |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
410 adding a '.0' would produce too many significant digits (see issue 5864). |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
411 |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
412 Returns a pointer to the fixed buffer, or NULL on failure. |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
413 */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
414 Py_LOCAL_INLINE(char *) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
415 ensure_decimal_point(char* buffer, size_t buf_size, int precision) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
416 { |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
417 int digit_count, insert_count = 0, convert_to_exp = 0; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
418 char* chars_to_insert, *digits_start; |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
419 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
420 /* 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
|
421 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
|
422 if (*p == '-' || *p == '+') |
|
40db45bfc0f2
Fix issue 3411: default float format spec fails on negative numbers.
Eric Smith <eric@trueblade.com>
parents:
47815
diff
changeset
|
423 /* 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
|
424 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
|
425 ++p; |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
426 digits_start = p; |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
427 while (*p && Py_ISDIGIT(*p)) |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
428 ++p; |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
429 digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
430 |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
431 if (*p == '.') { |
|
53539
4bdd847b57c2
Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors.
Eric Smith <eric@trueblade.com>
parents:
53477
diff
changeset
|
432 if (Py_ISDIGIT(*(p+1))) { |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
433 /* 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
|
434 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
|
435 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
436 else { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
437 /* 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
|
438 digit. Insert a zero after the decimal. */ |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
439 /* can't ever get here via PyOS_double_to_string */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
440 assert(precision == -1); |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
441 ++p; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
442 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
|
443 insert_count = 1; |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
444 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
445 } |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
446 else if (!(*p == 'e' || *p == 'E')) { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
447 /* Don't add ".0" if we have an exponent. */ |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
448 if (digit_count == precision) { |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
449 /* issue 5864: don't add a trailing .0 in the case |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
450 where the '%g'-formatted result already has as many |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
451 significant digits as were requested. Switch to |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
452 exponential notation instead. */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
453 convert_to_exp = 1; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
454 /* no exponent, no point, and we shouldn't land here |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
455 for infs and nans, so we must be at the end of the |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
456 string. */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
457 assert(*p == '\0'); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
458 } |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
459 else { |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
460 assert(precision == -1 || digit_count < precision); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
461 chars_to_insert = ".0"; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
462 insert_count = 2; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
463 } |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
464 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
465 if (insert_count) { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
466 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
|
467 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
|
468 /* 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
|
469 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
|
470 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
|
471 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
472 else { |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
473 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
|
474 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
|
475 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
|
476 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
477 } |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
478 if (convert_to_exp) { |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
479 int written; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
480 size_t buf_avail; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
481 p = digits_start; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
482 /* insert decimal point */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
483 assert(digit_count >= 1); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
484 memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
485 p[1] = '.'; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
486 p += digit_count+1; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
487 assert(p <= buf_size+buffer); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
488 buf_avail = buf_size+buffer-p; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
489 if (buf_avail == 0) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
490 return NULL; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
491 /* Add exponent. It's okay to use lower case 'e': we only |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
492 arrive here as a result of using the empty format code or |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
493 repr/str builtins and those never want an upper case 'E' */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
494 written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
495 if (!(0 <= written && |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
496 written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
497 /* output truncated, or something else bad happened */ |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
498 return NULL; |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
499 remove_trailing_zeros(buffer); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
500 } |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
501 return buffer; |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
502 } |
|
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
503 |
|
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
|
504 /* 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
|
505 #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
|
506 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
507 /** |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
508 * _PyOS_ascii_formatd: |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
509 * @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
|
510 * @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
|
511 * @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
|
512 * code to use for converting. |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
513 * @d: The #gdouble to convert |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
514 * |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
515 * 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
|
516 * 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
|
517 * a printf()-style format string. Allowed conversion |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
518 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
519 * |
|
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
|
520 * '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
|
521 * 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
|
522 * |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
523 * Return value: The pointer to the buffer with the converted string. |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
524 * On failure returns NULL but does not set any Python exception. |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
525 **/ |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
526 /* DEPRECATED, will be deleted in 2.8 and 3.2 */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
527 PyAPI_FUNC(char *) |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
528 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
|
529 size_t buf_size, |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
530 const char *format, |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
531 double d) |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
532 { |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
533 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
|
534 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
|
535 |
|
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
|
536 /* 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
|
537 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
|
538 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
|
539 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
540 if (PyErr_WarnEx(PyExc_DeprecationWarning, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
541 "PyOS_ascii_formatd is deprecated, " |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
542 "use PyOS_double_to_string instead", 1) < 0) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
543 return NULL; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
544 |
|
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
|
545 /* 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
|
546 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
|
547 |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
548 if (format[0] != '%') |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
549 return NULL; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
550 |
|
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
|
551 /* 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
|
552 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
|
553 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
|
554 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
|
555 if (strpbrk(format + 1, "'l%")) |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
556 return NULL; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
557 |
|
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
|
558 /* 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
|
559 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
|
560 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
|
561 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
|
562 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
563 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
|
564 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
|
565 format_char == 'g' || format_char == 'G' || |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
566 format_char == 'Z')) |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
567 return NULL; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
568 |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
569 /* Map 'Z' format_char to 'g', by copying the format string and |
|
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
|
570 replacing the final char with a 'g' */ |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
571 if (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
|
572 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
|
573 /* 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
|
574 practice, this will never happen and will be |
|
16732db00822
Reformated lines > 79 chars.
Eric Smith <eric@trueblade.com>
parents:
45785
diff
changeset
|
575 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
|
576 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
|
577 } |
|
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
|
578 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
|
579 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
|
580 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
|
581 } |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
582 |
|
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
|
583 |
|
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
|
584 /* 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
|
585 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
|
586 |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
587 /* 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
|
588 |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
589 /* Get the current locale, and find the decimal point string. |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
590 Convert that string back to a dot. */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
591 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
|
592 |
|
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
|
593 /* 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
|
594 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
|
595 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
|
596 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
|
597 back to MIN_EXPONENT_DIGITS */ |
|
53477
bfb47bc1d051
Fix typo in function name
Mark Dickinson <dickinsm@gmail.com>
parents:
53470
diff
changeset
|
598 ensure_minimum_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
|
599 |
|
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
|
600 /* If format_char is 'Z', make sure we have at least one character |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
601 after the decimal point (and make sure we have a decimal point); |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
602 also switch to exponential notation in some edge cases where the |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
603 extra character would produce more significant digits that we |
|
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
604 really want. */ |
|
46600
37d645b01523
Issue 2526, float.__format__ 'n' specifier does not support thousands grouping.
Eric Smith <eric@trueblade.com>
parents:
45786
diff
changeset
|
605 if (format_char == 'Z') |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
606 buffer = ensure_decimal_point(buffer, buf_size, -1); |
|
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
|
607 |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
608 return buffer; |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
609 } |
|
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
610 |
|
53618
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
611 /* Precisions used by repr() and str(), respectively. |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
612 |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
613 The repr() precision (17 significant decimal digits) is the minimal number |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
614 that is guaranteed to have enough precision so that if the number is read |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
615 back in the exact same binary value is recreated. This is true for IEEE |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
616 floating point by design, and also happens to work for all other modern |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
617 hardware. |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
618 |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
619 The str() precision (12 significant decimal digits) is chosen so that in |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
620 most cases, the rounding noise created by various operations is suppressed, |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
621 while giving plenty of precision for practical use. |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
622 |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
623 */ |
|
4762394fc26c
Remove format_float and use _PyOS_double_to_string instead.
Mark Dickinson <dickinsm@gmail.com>
parents:
53611
diff
changeset
|
624 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
625 PyAPI_FUNC(void) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
626 _PyOS_double_to_string(char *buf, size_t buf_len, double val, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
627 char format_code, int precision, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
628 int flags, int *ptype) |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
629 { |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
630 char format[32]; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
631 int t; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
632 int upper = 0; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
633 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
634 if (buf_len < 1) { |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
635 assert(0); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
636 /* There's no way to signal this error. Just return. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
637 return; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
638 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
639 buf[0] = 0; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
640 |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
641 /* Validate format_code, and map upper and lower case */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
642 switch (format_code) { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
643 case 'e': /* exponent */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
644 case 'f': /* fixed */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
645 case 'g': /* general */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
646 break; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
647 case 'E': |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
648 upper = 1; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
649 format_code = 'e'; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
650 break; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
651 case 'F': |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
652 upper = 1; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
653 format_code = 'f'; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
654 break; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
655 case 'G': |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
656 upper = 1; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
657 format_code = 'g'; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
658 break; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
659 case 'r': /* repr format */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
660 /* Supplied precision is unused, must be 0. */ |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
661 if (precision != 0) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
662 return; |
|
53802
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
663 /* The repr() precision (17 significant decimal digits) is the |
|
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
664 minimal number that is guaranteed to have enough precision |
|
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
665 so that if the number is read back in the exact same binary |
|
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
666 value is recreated. This is true for IEEE floating point |
|
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
667 by design, and also happens to work for all other modern |
|
1d8f24d40c2c
Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
Eric Smith <eric@trueblade.com>
parents:
53716
diff
changeset
|
668 hardware. */ |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
669 precision = 17; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
670 format_code = 'g'; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
671 break; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
672 default: |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
673 assert(0); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
674 return; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
675 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
676 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
677 /* Check for buf too small to fit "-inf". Other buffer too small |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
678 conditions are dealt with when converting or formatting finite |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
679 numbers. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
680 if (buf_len < 5) { |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
681 assert(0); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
682 return; |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
683 } |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
684 |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
685 /* Handle nan and inf. */ |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
686 if (Py_IS_NAN(val)) { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
687 strcpy(buf, "nan"); |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
688 t = Py_DTST_NAN; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
689 } else if (Py_IS_INFINITY(val)) { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
690 if (copysign(1., val) == 1.) |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
691 strcpy(buf, "inf"); |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
692 else |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
693 strcpy(buf, "-inf"); |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
694 t = Py_DTST_INFINITE; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
695 } else { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
696 t = Py_DTST_FINITE; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
697 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
698 /* Build the format string. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
699 PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
700 (flags & Py_DTSF_ALT ? "#" : ""), precision, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
701 format_code); |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
702 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
703 /* Have PyOS_snprintf do the hard work. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
704 PyOS_snprintf(buf, buf_len, format, val); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
705 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
706 /* Do various fixups on the return string */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
707 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
708 /* Get the current locale, and find the decimal point string. |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
709 Convert that string back to a dot. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
710 change_decimal_from_locale_to_dot(buf); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
711 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
712 /* If an exponent exists, ensure that the exponent is at least |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
713 MIN_EXPONENT_DIGITS digits, providing the buffer is large |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
714 enough for the extra zeros. Also, if there are more than |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
715 MIN_EXPONENT_DIGITS, remove as many zeros as possible until |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
716 we get back to MIN_EXPONENT_DIGITS */ |
|
53477
bfb47bc1d051
Fix typo in function name
Mark Dickinson <dickinsm@gmail.com>
parents:
53470
diff
changeset
|
717 ensure_minimum_exponent_length(buf, buf_len); |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
718 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
719 /* Possibly make sure we have at least one character after the |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
720 decimal point (and make sure we have a decimal point). */ |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
721 if (flags & Py_DTSF_ADD_DOT_0) |
|
53611
a3fcccee8957
Issue #5864: format(1234.5, '.4') gives misleading result
Mark Dickinson <dickinsm@gmail.com>
parents:
53555
diff
changeset
|
722 buf = ensure_decimal_point(buf, buf_len, precision); |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
723 } |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
724 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
725 /* Add the sign if asked and the result isn't negative. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
726 if (flags & Py_DTSF_SIGN && buf[0] != '-') |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
727 ensure_sign(buf, buf_len); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
728 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
729 if (upper) { |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
730 /* Convert to upper case. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
731 char *p; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
732 for (p = buf; *p; p++) |
|
53712
1f00bc1d115a
Eliminate some locale-dependent calls to isspace and tolower.
Mark Dickinson <dickinsm@gmail.com>
parents:
53618
diff
changeset
|
733 *p = Py_TOUPPER(*p); |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
734 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
735 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
736 if (ptype) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
737 *ptype = t; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
738 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
739 |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
740 |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
741 PyAPI_FUNC(char *) PyOS_double_to_string(double val, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
742 char format_code, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
743 int precision, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
744 int flags, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
745 int *ptype) |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
746 { |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
747 char buf[128]; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
748 Py_ssize_t len; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
749 char *result; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
750 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
751 _PyOS_double_to_string(buf, sizeof(buf), val, format_code, precision, |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
752 flags, ptype); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
753 len = strlen(buf); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
754 if (len == 0) { |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
755 PyErr_BadInternalCall(); |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
756 return NULL; |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
757 } |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
758 |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
759 /* Add 1 for the trailing 0 byte. */ |
|
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
760 result = PyMem_Malloc(len + 1); |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
761 if (result == NULL) { |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
762 PyErr_NoMemory(); |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
763 return NULL; |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
764 } |
|
53442
6947bc3dd433
Issue #5835, deprecate PyOS_ascii_formatd.
Eric Smith <eric@trueblade.com>
parents:
53338
diff
changeset
|
765 strcpy(result, buf); |
|
53312
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
766 |
|
c5e0d9beebf9
Backport of some of the work in r71665 to trunk. This reworks much of
Eric Smith <eric@trueblade.com>
parents:
48021
diff
changeset
|
767 return result; |
|
32305
13656d58d450
Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff
changeset
|
768 } |
