annotate Python/pystrtod.c @ 76451:ea46ebba8a0f

Issue #13959: Re-implement imp.source_from_cache() in Lib/imp.py.
author Brett Cannon <brett@python.org>
date Sat, 21 Apr 2012 18:52:52 -0400
parents b39270c6b8d1
children c468511fc887
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 /* -*- Mode: C; c-file-style: "python" -*- */
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3 #include <Python.h>
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
4 #include <locale.h>
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
5
56752
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
6 /* Case-insensitive string match used for nan and inf detection; t should be
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
7 lower-case. Returns 1 for a successful match, 0 otherwise. */
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
8
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
9 static int
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
10 case_insensitive_match(const char *s, const char *t)
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
11 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
12 while(*t && Py_TOLOWER(*s) == *t) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
13 s++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
14 t++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
15 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
16 return *t ? 0 : 1;
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
17 }
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
18
56752
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
19 /* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
20 "infinity", with an optional leading sign of "+" or "-". On success,
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
21 return the NaN or Infinity as a double and set *endptr to point just beyond
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
22 the successfully parsed portion of the string. On failure, return -1.0 and
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
23 set *endptr to point to the start of the string. */
f598843f3695 Move some comments to more appropriate places
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
24
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
25 double
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
26 _Py_parse_inf_or_nan(const char *p, char **endptr)
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
27 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
28 double retval;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
29 const char *s;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
30 int negate = 0;
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
31
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
32 s = p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
33 if (*s == '-') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
34 negate = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
35 s++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
36 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
37 else if (*s == '+') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
38 s++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
39 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
40 if (case_insensitive_match(s, "inf")) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
41 s += 3;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
42 if (case_insensitive_match(s, "inity"))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
43 s += 5;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
44 retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
45 }
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
46 #ifdef Py_NAN
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
47 else if (case_insensitive_match(s, "nan")) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
48 s += 3;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
49 retval = negate ? -Py_NAN : Py_NAN;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
50 }
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
51 #endif
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
52 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
53 s = p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
54 retval = -1.0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
55 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
56 *endptr = (char *)s;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
57 return retval;
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
58 }
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
59
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
60 /**
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
61 * _PyOS_ascii_strtod:
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62 * @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
63 * @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
64 * the last character used in the conversion.
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
65 *
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
66 * 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
67 * 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
68 * 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
69 * 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
70 * thread-safe.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
71 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
72 * 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
73 * 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
74 * 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
75 * locale-sensitive system strtod() function.
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 * 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
78 * 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
79 * 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
80 * zero is returned and %ERANGE is stored in %errno.
38669
19fd6141940d Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents: 38453
diff changeset
81 * If memory allocation fails, %ENOMEM is stored in %errno.
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
82 *
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
83 * 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
84 * 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
85 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
86 * Return value: the #gdouble value.
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
87 **/
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
88
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
89 #ifndef PY_NO_SHORT_FLOAT_REPR
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
90
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
91 static double
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
92 _PyOS_ascii_strtod(const char *nptr, char **endptr)
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
93 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
94 double result;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
95 _Py_SET_53BIT_PRECISION_HEADER;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
96
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
97 assert(nptr != NULL);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
98 /* Set errno to zero, so that we can distinguish zero results
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
99 and underflows */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
100 errno = 0;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
101
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
102 _Py_SET_53BIT_PRECISION_START;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
103 result = _Py_dg_strtod(nptr, endptr);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
104 _Py_SET_53BIT_PRECISION_END;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
105
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
106 if (*endptr == nptr)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
107 /* string might represent an inf or nan */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
108 result = _Py_parse_inf_or_nan(nptr, endptr);
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
109
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
110 return result;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
111
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
112 }
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
113
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
114 #else
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
115
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
116 /*
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
117 Use system strtod; since strtod is locale aware, we may
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
118 have to first fix the decimal separator.
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
119
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
120 Note that unlike _Py_dg_strtod, the system strtod may not always give
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
121 correctly rounded results.
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
122 */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
123
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
124 static double
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
125 _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
126 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
127 char *fail_pos;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
128 double val = -1.0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
129 struct lconv *locale_data;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
130 const char *decimal_point;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
131 size_t decimal_point_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
132 const char *p, *decimal_point_pos;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
133 const char *end = NULL; /* Silence gcc */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
134 const char *digits_pos = NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
135 int negate = 0;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
136
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
137 assert(nptr != NULL);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
138
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
139 fail_pos = NULL;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
140
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
141 locale_data = localeconv();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
142 decimal_point = locale_data->decimal_point;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
143 decimal_point_len = strlen(decimal_point);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
144
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
145 assert(decimal_point_len != 0);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
146
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
147 decimal_point_pos = NULL;
44535
420fe6d7d5f4 Merged revisions 59703-59773 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 39442
diff changeset
148
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
149 /* Parse infinities and nans */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
150 val = _Py_parse_inf_or_nan(nptr, endptr);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
151 if (*endptr != nptr)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
152 return val;
54232
4501b638fc3f Refactor to remove duplicated nan/inf parsing code in
Mark Dickinson <dickinsm@gmail.com>
parents: 53787
diff changeset
153
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
154 /* Set errno to zero, so that we can distinguish zero results
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
155 and underflows */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
156 errno = 0;
53468
f76572108dd7 Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents: 53332
diff changeset
157
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
158 /* We process the optional sign manually, then pass the remainder to
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
159 the system strtod. This ensures that the result of an underflow
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
160 has the correct sign. (bug #1725) */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
161 p = nptr;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
162 /* Process leading sign, if present */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
163 if (*p == '-') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
164 negate = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
165 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
166 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
167 else if (*p == '+') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
168 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
169 }
44535
420fe6d7d5f4 Merged revisions 59703-59773 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 39442
diff changeset
170
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
171 /* Some platform strtods accept hex floats; Python shouldn't (at the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
172 moment), so we check explicitly for strings starting with '0x'. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
173 if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X'))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
174 goto invalid_string;
53468
f76572108dd7 Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents: 53332
diff changeset
175
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
176 /* Check that what's left begins with a digit or decimal point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
177 if (!Py_ISDIGIT(*p) && *p != '.')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
178 goto invalid_string;
53468
f76572108dd7 Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents: 53332
diff changeset
179
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
180 digits_pos = p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
181 if (decimal_point[0] != '.' ||
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
182 decimal_point[1] != 0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
183 {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
184 /* Look for a '.' in the input; if present, it'll need to be
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
185 swapped for the current locale's decimal point before we
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
186 call strtod. On the other hand, if we find the current
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
187 locale's decimal point then the input is invalid. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
188 while (Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
189 p++;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
190
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
191 if (*p == '.')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
192 {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
193 decimal_point_pos = p++;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
194
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
195 /* locate end of number */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
196 while (Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
197 p++;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
198
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
199 if (*p == 'e' || *p == 'E')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
200 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
201 if (*p == '+' || *p == '-')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
202 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
203 while (Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
204 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
205 end = p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
206 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
207 else if (strncmp(p, decimal_point, decimal_point_len) == 0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
208 /* Python bug #1417699 */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
209 goto invalid_string;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
210 /* For the other cases, we need not convert the decimal
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
211 point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
212 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
213
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
214 if (decimal_point_pos) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
215 char *copy, *c;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
216 /* Create a copy of the input, with the '.' converted to the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
217 locale-specific decimal point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
218 copy = (char *)PyMem_MALLOC(end - digits_pos +
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
219 1 + decimal_point_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
220 if (copy == NULL) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
221 *endptr = (char *)nptr;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
222 errno = ENOMEM;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
223 return val;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
224 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
225
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
226 c = copy;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
227 memcpy(c, digits_pos, decimal_point_pos - digits_pos);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
228 c += decimal_point_pos - digits_pos;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
229 memcpy(c, decimal_point, decimal_point_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
230 c += decimal_point_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
231 memcpy(c, decimal_point_pos + 1,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
232 end - (decimal_point_pos + 1));
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
233 c += end - (decimal_point_pos + 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
234 *c = 0;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
235
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
236 val = strtod(copy, &fail_pos);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
237
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
238 if (fail_pos)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
239 {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
240 if (fail_pos > decimal_point_pos)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
241 fail_pos = (char *)digits_pos +
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
242 (fail_pos - copy) -
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
243 (decimal_point_len - 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
244 else
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
245 fail_pos = (char *)digits_pos +
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
246 (fail_pos - copy);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
247 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
248
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
249 PyMem_FREE(copy);
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
250
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
251 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
252 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
253 val = strtod(digits_pos, &fail_pos);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
254 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
255
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
256 if (fail_pos == digits_pos)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
257 goto invalid_string;
44535
420fe6d7d5f4 Merged revisions 59703-59773 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 39442
diff changeset
258
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
259 if (negate && fail_pos != nptr)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
260 val = -val;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
261 *endptr = fail_pos;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
262
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
263 return val;
53468
f76572108dd7 Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents: 53332
diff changeset
264
f76572108dd7 Internal plumbing changes for float parsing:
Mark Dickinson <dickinsm@gmail.com>
parents: 53332
diff changeset
265 invalid_string:
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
266 *endptr = (char*)nptr;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
267 errno = EINVAL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
268 return -1.0;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
269 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
270
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
271 #endif
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
272
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
273 /* PyOS_string_to_double converts a null-terminated byte string s (interpreted
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
274 as a string of ASCII characters) to a float. The string should not have
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
275 leading or trailing whitespace. The conversion is independent of the
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
276 current locale.
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
277
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
278 If endptr is NULL, try to convert the whole string. Raise ValueError and
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
279 return -1.0 if the string is not a valid representation of a floating-point
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
280 number.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
281
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
282 If endptr is non-NULL, try to convert as much of the string as possible.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
283 If no initial segment of the string is the valid representation of a
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
284 floating-point number then *endptr is set to point to the beginning of the
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
285 string, -1.0 is returned and again ValueError is raised.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
286
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
287 On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
288 if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
289 exception is raised. Otherwise, overflow_exception should point to a
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
290 a Python exception, this exception will be raised, -1.0 will be returned,
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
291 and *endptr will point just past the end of the converted value.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
292
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
293 If any other failure occurs (for example lack of memory), -1.0 is returned
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
294 and the appropriate Python exception will have been set.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
295 */
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
296
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
297 double
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
298 PyOS_string_to_double(const char *s,
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
299 char **endptr,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
300 PyObject *overflow_exception)
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
301 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
302 double x, result=-1.0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
303 char *fail_pos;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
304
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
305 errno = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
306 PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
307 x = _PyOS_ascii_strtod(s, &fail_pos);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
308 PyFPE_END_PROTECT(x)
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
309
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
310 if (errno == ENOMEM) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
311 PyErr_NoMemory();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
312 fail_pos = (char *)s;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
313 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
314 else if (!endptr && (fail_pos == s || *fail_pos != '\0'))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
315 PyErr_Format(PyExc_ValueError,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
316 "could not convert string to float: "
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
317 "%.200s", s);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
318 else if (fail_pos == s)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
319 PyErr_Format(PyExc_ValueError,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
320 "could not convert string to float: "
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
321 "%.200s", s);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
322 else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
323 PyErr_Format(overflow_exception,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
324 "value too large to convert to float: "
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
325 "%.200s", s);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
326 else
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
327 result = x;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
328
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
329 if (endptr != NULL)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
330 *endptr = fail_pos;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
331 return result;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53640
diff changeset
332 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
333
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
334 #ifdef PY_NO_SHORT_FLOAT_REPR
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
335
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
336 /* Given a string that may have a decimal point in the current
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
337 locale, change it back to a dot. Since the string cannot get
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
338 longer, no need for a maximum buffer size parameter. */
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
339 Py_LOCAL_INLINE(void)
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
340 change_decimal_from_locale_to_dot(char* buffer)
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
341 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
342 struct lconv *locale_data = localeconv();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
343 const char *decimal_point = locale_data->decimal_point;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
344
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
345 if (decimal_point[0] != '.' || decimal_point[1] != 0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
346 size_t decimal_point_len = strlen(decimal_point);
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
347
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
348 if (*buffer == '+' || *buffer == '-')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
349 buffer++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
350 while (Py_ISDIGIT(*buffer))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
351 buffer++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
352 if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
353 *buffer = '.';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
354 buffer++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
355 if (decimal_point_len > 1) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
356 /* buffer needs to get smaller */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
357 size_t rest_len = strlen(buffer +
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
358 (decimal_point_len - 1));
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
359 memmove(buffer,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
360 buffer + (decimal_point_len - 1),
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
361 rest_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
362 buffer[rest_len] = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
363 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
364 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
365 }
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
366 }
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
367
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
368
45435
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
369 /* From the C99 standard, section 7.19.6:
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
370 The exponent always contains at least two digits, and only as many more digits
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
371 as necessary to represent the exponent.
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
372 */
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
373 #define MIN_EXPONENT_DIGITS 2
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
374
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
375 /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
376 in length. */
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
377 Py_LOCAL_INLINE(void)
53479
785ea299fe23 Merged revisions 71976 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 53468
diff changeset
378 ensure_minimum_exponent_length(char* buffer, size_t buf_size)
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
379 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
380 char *p = strpbrk(buffer, "eE");
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
381 if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
382 char *start = p + 2;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
383 int exponent_digit_cnt = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
384 int leading_zero_cnt = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
385 int in_leading_zeros = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
386 int significant_digit_cnt;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
387
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
388 /* Skip over the exponent and the sign. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
389 p += 2;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
390
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
391 /* Find the end of the exponent, keeping track of leading
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
392 zeros. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
393 while (*p && Py_ISDIGIT(*p)) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
394 if (in_leading_zeros && *p == '0')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
395 ++leading_zero_cnt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
396 if (*p != '0')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
397 in_leading_zeros = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
398 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
399 ++exponent_digit_cnt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
400 }
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
401
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
402 significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
403 if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
404 /* If there are 2 exactly digits, we're done,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
405 regardless of what they contain */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
406 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
407 else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
408 int extra_zeros_cnt;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
409
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
410 /* There are more than 2 digits in the exponent. See
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
411 if we can delete some of the leading zeros */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
412 if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
413 significant_digit_cnt = MIN_EXPONENT_DIGITS;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
414 extra_zeros_cnt = exponent_digit_cnt -
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
415 significant_digit_cnt;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
416
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
417 /* Delete extra_zeros_cnt worth of characters from the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
418 front of the exponent */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
419 assert(extra_zeros_cnt >= 0);
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
420
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
421 /* Add one to significant_digit_cnt to copy the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
422 trailing 0 byte, thus setting the length */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
423 memmove(start,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
424 start + extra_zeros_cnt,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
425 significant_digit_cnt + 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
426 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
427 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
428 /* If there are fewer than 2 digits, add zeros
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
429 until there are 2, if there's enough room */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
430 int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
431 if (start + zeros + exponent_digit_cnt + 1
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
432 < buffer + buf_size) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
433 memmove(start + zeros, start,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
434 exponent_digit_cnt + 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
435 memset(start, '0', zeros);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
436 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
437 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
438 }
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
439 }
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
440
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
441 /* Remove trailing zeros after the decimal point from a numeric string; also
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
442 remove the decimal point if all digits following it are zero. The numeric
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
443 string must end in '\0', and should not have any leading or trailing
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
444 whitespace. Assumes that the decimal point is '.'. */
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
445 Py_LOCAL_INLINE(void)
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
446 remove_trailing_zeros(char *buffer)
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
447 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
448 char *old_fraction_end, *new_fraction_end, *end, *p;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
449
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
450 p = buffer;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
451 if (*p == '-' || *p == '+')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
452 /* Skip leading sign, if present */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
453 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
454 while (Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
455 ++p;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
456
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
457 /* if there's no decimal point there's nothing to do */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
458 if (*p++ != '.')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
459 return;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
460
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
461 /* scan any digits after the point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
462 while (Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
463 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
464 old_fraction_end = p;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
465
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
466 /* scan up to ending '\0' */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
467 while (*p != '\0')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
468 p++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
469 /* +1 to make sure that we move the null byte as well */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
470 end = p+1;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
471
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
472 /* scan back from fraction_end, looking for removable zeros */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
473 p = old_fraction_end;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
474 while (*(p-1) == '0')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
475 --p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
476 /* and remove point if we've got that far */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
477 if (*(p-1) == '.')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
478 --p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
479 new_fraction_end = p;
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
480
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
481 memmove(new_fraction_end, old_fraction_end, end-old_fraction_end);
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
482 }
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
483
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
484 /* Ensure that buffer has a decimal point in it. The decimal point will not
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
485 be in the current locale, it will always be '.'. Don't add a decimal point
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
486 if an exponent is present. Also, convert to exponential notation where
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
487 adding a '.0' would produce too many significant digits (see issue 5864).
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
488
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
489 Returns a pointer to the fixed buffer, or NULL on failure.
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
490 */
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
491 Py_LOCAL_INLINE(char *)
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
492 ensure_decimal_point(char* buffer, size_t buf_size, int precision)
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
493 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
494 int digit_count, insert_count = 0, convert_to_exp = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
495 char *chars_to_insert, *digits_start;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
496
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
497 /* search for the first non-digit character */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
498 char *p = buffer;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
499 if (*p == '-' || *p == '+')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
500 /* Skip leading sign, if present. I think this could only
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
501 ever be '-', but it can't hurt to check for both. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
502 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
503 digits_start = p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
504 while (*p && Py_ISDIGIT(*p))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
505 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
506 digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int);
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
507
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
508 if (*p == '.') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
509 if (Py_ISDIGIT(*(p+1))) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
510 /* Nothing to do, we already have a decimal
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
511 point and a digit after it */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
512 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
513 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
514 /* We have a decimal point, but no following
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
515 digit. Insert a zero after the decimal. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
516 /* can't ever get here via PyOS_double_to_string */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
517 assert(precision == -1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
518 ++p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
519 chars_to_insert = "0";
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
520 insert_count = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
521 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
522 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
523 else if (!(*p == 'e' || *p == 'E')) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
524 /* Don't add ".0" if we have an exponent. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
525 if (digit_count == precision) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
526 /* issue 5864: don't add a trailing .0 in the case
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
527 where the '%g'-formatted result already has as many
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
528 significant digits as were requested. Switch to
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
529 exponential notation instead. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
530 convert_to_exp = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
531 /* no exponent, no point, and we shouldn't land here
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
532 for infs and nans, so we must be at the end of the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
533 string. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
534 assert(*p == '\0');
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
535 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
536 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
537 assert(precision == -1 || digit_count < precision);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
538 chars_to_insert = ".0";
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
539 insert_count = 2;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
540 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
541 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
542 if (insert_count) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
543 size_t buf_len = strlen(buffer);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
544 if (buf_len + insert_count + 1 >= buf_size) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
545 /* If there is not enough room in the buffer
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
546 for the additional text, just skip it. It's
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
547 not worth generating an error over. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
548 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
549 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
550 memmove(p + insert_count, p,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
551 buffer + strlen(buffer) - p + 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
552 memcpy(p, chars_to_insert, insert_count);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
553 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
554 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
555 if (convert_to_exp) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
556 int written;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
557 size_t buf_avail;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
558 p = digits_start;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
559 /* insert decimal point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
560 assert(digit_count >= 1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
561 memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
562 p[1] = '.';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
563 p += digit_count+1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
564 assert(p <= buf_size+buffer);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
565 buf_avail = buf_size+buffer-p;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
566 if (buf_avail == 0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
567 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
568 /* Add exponent. It's okay to use lower case 'e': we only
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
569 arrive here as a result of using the empty format code or
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
570 repr/str builtins and those never want an upper case 'E' */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
571 written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
572 if (!(0 <= written &&
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
573 written < Py_SAFE_DOWNCAST(buf_avail, size_t, int)))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
574 /* output truncated, or something else bad happened */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
575 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
576 remove_trailing_zeros(buffer);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
577 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
578 return buffer;
46601
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
579 }
7b4081bec783 Merged revisions 62586 via svnmerge from
Eric Smith <eric@trueblade.com>
parents: 45852
diff changeset
580
45435
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
581 /* see FORMATBUFLEN in unicodeobject.c */
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
582 #define FLOAT_FORMATBUFLEN 120
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
583
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
584 /**
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
585 * _PyOS_ascii_formatd:
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
586 * @buffer: A buffer to place the resulting string in
45852
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
587 * @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
588 * @format: The printf()-style format to use for the
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
589 * code to use for converting.
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
590 * @d: The #gdouble to convert
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
591 * @precision: The precision to use when formatting.
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
592 *
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
593 * 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
594 * 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
595 * a printf()-style format string. Allowed conversion
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
596 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
597 *
45852
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
598 * 'Z' is the same as 'g', except it always has a decimal and
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
599 * at least one digit after the decimal.
45435
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
600 *
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
601 * Return value: The pointer to the buffer with the converted string.
53603
3759839b9fa5 Issue #5864: Fix problem with empty code formatting for floats,
Mark Dickinson <dickinsm@gmail.com>
parents: 53543
diff changeset
602 * 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
603 **/
59000
f0acf2138a96 Issue #5988: Delete deprecated functions PyOS_ascii_formatd, PyOS_ascii_strtod, and PyOS_ascii_atof.
Eric Smith <eric@trueblade.com>
parents: 58467
diff changeset
604 static char *
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
605 _PyOS_ascii_formatd(char *buffer,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
606 size_t buf_size,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
607 const char *format,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
608 double d,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
609 int precision)
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
610 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
611 char format_char;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
612 size_t format_len = strlen(format);
45435
42b3b117391d Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44535
diff changeset
613
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
614 /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
615 also with at least one character past the decimal. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
616 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
617
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
618 /* The last character in the format string must be the format char */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
619 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
620
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
621 if (format[0] != '%')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
622 return NULL;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
623
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
624 /* I'm not sure why this test is here. It's ensuring that the format
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
625 string after the first character doesn't have a single quote, a
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
626 lowercase l, or a percent. This is the reverse of the commented-out
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
627 test about 10 lines ago. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
628 if (strpbrk(format + 1, "'l%"))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
629 return NULL;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
630
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
631 /* Also curious about this function is that it accepts format strings
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
632 like "%xg", which are invalid for floats. In general, the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
633 interface to this function is not very good, but changing it is
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
634 difficult because it's a public API. */
45852
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
635
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
636 if (!(format_char == 'e' || format_char == 'E' ||
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
637 format_char == 'f' || format_char == 'F' ||
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
638 format_char == 'g' || format_char == 'G' ||
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
639 format_char == 'Z'))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
640 return NULL;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
641
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
642 /* Map 'Z' format_char to 'g', by copying the format string and
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
643 replacing the final char with a 'g' */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
644 if (format_char == 'Z') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
645 if (format_len + 1 >= sizeof(tmp_format)) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
646 /* The format won't fit in our copy. Error out. In
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
647 practice, this will never happen and will be
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
648 detected by returning NULL */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
649 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
650 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
651 strcpy(tmp_format, format);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
652 tmp_format[format_len - 1] = 'g';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
653 format = tmp_format;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
654 }
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
655
45852
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
656
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
657 /* Have PyOS_snprintf do the hard work */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
658 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
659
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
660 /* 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
661
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
662 /* Get the current locale, and find the decimal point string.
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
663 Convert that string back to a dot. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
664 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
665
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
666 /* If an exponent exists, ensure that the exponent is at least
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
667 MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
668 for the extra zeros. Also, if there are more than
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
669 MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
670 back to MIN_EXPONENT_DIGITS */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
671 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
672
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
673 /* If format_char is 'Z', make sure we have at least one character
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
674 after the decimal point (and make sure we have a decimal point);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
675 also switch to exponential notation in some edge cases where the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
676 extra character would produce more significant digits that we
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
677 really want. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
678 if (format_char == 'Z')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
679 buffer = ensure_decimal_point(buffer, buf_size, precision);
45852
30c4e1ca8421 Merged revisions 61431,61433-61436,61439,61444,61449-61450,61453,61458,61465,61468,61471-61474,61480,61483-61484,61488,61495-61496,61498,61503-61504,61507,61509-61510,61515-61518 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45435
diff changeset
680
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
681 return buffer;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
682 }
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
683
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
684 /* The fallback code to use if _Py_dg_dtoa is not available. */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
685
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
686 PyAPI_FUNC(char *) PyOS_double_to_string(double val,
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
687 char format_code,
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
688 int precision,
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
689 int flags,
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
690 int *type)
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
691 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
692 char format[32];
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
693 Py_ssize_t bufsize;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
694 char *buf;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
695 int t, exp;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
696 int upper = 0;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
697
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
698 /* Validate format_code, and map upper and lower case */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
699 switch (format_code) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
700 case 'e': /* exponent */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
701 case 'f': /* fixed */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
702 case 'g': /* general */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
703 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
704 case 'E':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
705 upper = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
706 format_code = 'e';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
707 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
708 case 'F':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
709 upper = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
710 format_code = 'f';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
711 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
712 case 'G':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
713 upper = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
714 format_code = 'g';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
715 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
716 case 'r': /* repr format */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
717 /* Supplied precision is unused, must be 0. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
718 if (precision != 0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
719 PyErr_BadInternalCall();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
720 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
721 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
722 /* The repr() precision (17 significant decimal digits) is the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
723 minimal number that is guaranteed to have enough precision
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
724 so that if the number is read back in the exact same binary
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
725 value is recreated. This is true for IEEE floating point
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
726 by design, and also happens to work for all other modern
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
727 hardware. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
728 precision = 17;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
729 format_code = 'g';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
730 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
731 default:
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
732 PyErr_BadInternalCall();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
733 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
734 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
735
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
736 /* Here's a quick-and-dirty calculation to figure out how big a buffer
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
737 we need. In general, for a finite float we need:
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
738
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
739 1 byte for each digit of the decimal significand, and
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
740
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
741 1 for a possible sign
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
742 1 for a possible decimal point
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
743 2 for a possible [eE][+-]
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
744 1 for each digit of the exponent; if we allow 19 digits
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
745 total then we're safe up to exponents of 2**63.
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
746 1 for the trailing nul byte
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
747
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
748 This gives a total of 24 + the number of digits in the significand,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
749 and the number of digits in the significand is:
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
750
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
751 for 'g' format: at most precision, except possibly
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
752 when precision == 0, when it's 1.
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
753 for 'e' format: precision+1
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
754 for 'f' format: precision digits after the point, at least 1
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
755 before. To figure out how many digits appear before the point
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
756 we have to examine the size of the number. If fabs(val) < 1.0
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
757 then there will be only one digit before the point. If
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
758 fabs(val) >= 1.0, then there are at most
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
759
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
760 1+floor(log10(ceiling(fabs(val))))
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
761
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
762 digits before the point (where the 'ceiling' allows for the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
763 possibility that the rounding rounds the integer part of val
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
764 up). A safe upper bound for the above quantity is
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
765 1+floor(exp/3), where exp is the unique integer such that 0.5
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
766 <= fabs(val)/2**exp < 1.0. This exp can be obtained from
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
767 frexp.
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
768
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
769 So we allow room for precision+1 digits for all formats, plus an
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
770 extra floor(exp/3) digits for 'f' format.
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
771
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
772 */
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
773
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
774 if (Py_IS_NAN(val) || Py_IS_INFINITY(val))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
775 /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
776 bufsize = 5;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
777 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
778 bufsize = 25 + precision;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
779 if (format_code == 'f' && fabs(val) >= 1.0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
780 frexp(val, &exp);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
781 bufsize += exp/3;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
782 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
783 }
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
784
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
785 buf = PyMem_Malloc(bufsize);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
786 if (buf == NULL) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
787 PyErr_NoMemory();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
788 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
789 }
53640
e08e80e768c1 Issue #5859: Remove use of fixed-length buffers for float formatting
Mark Dickinson <dickinsm@gmail.com>
parents: 53603
diff changeset
790
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
791 /* Handle nan and inf. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
792 if (Py_IS_NAN(val)) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
793 strcpy(buf, "nan");
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
794 t = Py_DTST_NAN;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
795 } else if (Py_IS_INFINITY(val)) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
796 if (copysign(1., val) == 1.)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
797 strcpy(buf, "inf");
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
798 else
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
799 strcpy(buf, "-inf");
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
800 t = Py_DTST_INFINITE;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
801 } else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
802 t = Py_DTST_FINITE;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
803 if (flags & Py_DTSF_ADD_DOT_0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
804 format_code = 'Z';
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
805
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
806 PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
807 (flags & Py_DTSF_ALT ? "#" : ""), precision,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
808 format_code);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
809 _PyOS_ascii_formatd(buf, bufsize, format, val, precision);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
810 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
811
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
812 /* Add sign when requested. It's convenient (esp. when formatting
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
813 complex numbers) to include a sign even for inf and nan. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
814 if (flags & Py_DTSF_SIGN && buf[0] != '-') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
815 size_t len = strlen(buf);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
816 /* the bufsize calculations above should ensure that we've got
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
817 space to add a sign */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
818 assert((size_t)bufsize >= len+2);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
819 memmove(buf+1, buf, len+1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
820 buf[0] = '+';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
821 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
822 if (upper) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
823 /* Convert to upper case. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
824 char *p1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
825 for (p1 = buf; *p1; p1++)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
826 *p1 = Py_TOUPPER(*p1);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
827 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
828
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
829 if (type)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
830 *type = t;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
831 return buf;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
832 }
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
833
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
834 #else
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
835
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
836 /* _Py_dg_dtoa is available. */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
837
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
838 /* I'm using a lookup table here so that I don't have to invent a non-locale
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
839 specific way to convert to uppercase */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
840 #define OFS_INF 0
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
841 #define OFS_NAN 1
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
842 #define OFS_E 2
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
843
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
844 /* The lengths of these are known to the code below, so don't change them */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
845 static char *lc_float_strings[] = {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
846 "inf",
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
847 "nan",
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
848 "e",
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
849 };
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
850 static char *uc_float_strings[] = {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
851 "INF",
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
852 "NAN",
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
853 "E",
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
854 };
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
855
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
856
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
857 /* Convert a double d to a string, and return a PyMem_Malloc'd block of
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
858 memory contain the resulting string.
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
859
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
860 Arguments:
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
861 d is the double to be converted
53787
c6376d3fa968 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: 53718
diff changeset
862 format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g'
c6376d3fa968 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: 53718
diff changeset
863 correspond to '%e', '%f' and '%g'; 'r' corresponds to repr.
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
864 mode is one of '0', '2' or '3', and is completely determined by
53787
c6376d3fa968 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: 53718
diff changeset
865 format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0.
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
866 precision is the desired precision
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
867 always_add_sign is nonzero if a '+' sign should be included for positive
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
868 numbers
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
869 add_dot_0_if_integer is nonzero if integers in non-exponential form
53787
c6376d3fa968 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: 53718
diff changeset
870 should have ".0" added. Only applies to format codes 'r' and 'g'.
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
871 use_alt_formatting is nonzero if alternative formatting should be
53787
c6376d3fa968 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: 53718
diff changeset
872 used. Only applies to format codes 'e', 'f' and 'g'. For code 'g',
c6376d3fa968 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: 53718
diff changeset
873 at most one of use_alt_formatting and add_dot_0_if_integer should
c6376d3fa968 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: 53718
diff changeset
874 be nonzero.
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
875 type, if non-NULL, will be set to one of these constants to identify
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
876 the type of the 'd' argument:
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
877 Py_DTST_FINITE
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
878 Py_DTST_INFINITE
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
879 Py_DTST_NAN
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
880
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
881 Returns a PyMem_Malloc'd block of memory containing the resulting string,
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
882 or NULL on error. If NULL is returned, the Python error has been set.
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
883 */
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
884
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
885 static char *
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
886 format_float_short(double d, char format_code,
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
887 int mode, Py_ssize_t precision,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
888 int always_add_sign, int add_dot_0_if_integer,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
889 int use_alt_formatting, char **float_strings, int *type)
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
890 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
891 char *buf = NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
892 char *p = NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
893 Py_ssize_t bufsize = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
894 char *digits, *digits_end;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
895 int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
896 Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
897 _Py_SET_53BIT_PRECISION_HEADER;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
898
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
899 /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
900 Must be matched by a call to _Py_dg_freedtoa. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
901 _Py_SET_53BIT_PRECISION_START;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
902 digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
903 &digits_end);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
904 _Py_SET_53BIT_PRECISION_END;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
905
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
906 decpt = (Py_ssize_t)decpt_as_int;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
907 if (digits == NULL) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
908 /* The only failure mode is no memory. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
909 PyErr_NoMemory();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
910 goto exit;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
911 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
912 assert(digits_end != NULL && digits_end >= digits);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
913 digits_len = digits_end - digits;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
914
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
915 if (digits_len && !Py_ISDIGIT(digits[0])) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
916 /* Infinities and nans here; adapt Gay's output,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
917 so convert Infinity to inf and NaN to nan, and
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
918 ignore sign of nan. Then return. */
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
919
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
920 /* ignore the actual sign of a nan */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
921 if (digits[0] == 'n' || digits[0] == 'N')
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
922 sign = 0;
53332
330115137414 Issue #5816: Simplify code for parsing and printing of complex numbers.
Mark Dickinson <dickinsm@gmail.com>
parents: 53210
diff changeset
923
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
924 /* We only need 5 bytes to hold the result "+inf\0" . */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
925 bufsize = 5; /* Used later in an assert. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
926 buf = (char *)PyMem_Malloc(bufsize);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
927 if (buf == NULL) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
928 PyErr_NoMemory();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
929 goto exit;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
930 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
931 p = buf;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
932
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
933 if (sign == 1) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
934 *p++ = '-';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
935 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
936 else if (always_add_sign) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
937 *p++ = '+';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
938 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
939 if (digits[0] == 'i' || digits[0] == 'I') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
940 strncpy(p, float_strings[OFS_INF], 3);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
941 p += 3;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
942
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
943 if (type)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
944 *type = Py_DTST_INFINITE;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
945 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
946 else if (digits[0] == 'n' || digits[0] == 'N') {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
947 strncpy(p, float_strings[OFS_NAN], 3);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
948 p += 3;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
949
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
950 if (type)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
951 *type = Py_DTST_NAN;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
952 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
953 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
954 /* shouldn't get here: Gay's code should always return
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
955 something starting with a digit, an 'I', or 'N' */
62910
5025ba0553b6 Revert temporary debugging commits (r82752, r82754).
Mark Dickinson <dickinsm@gmail.com>
parents: 62909
diff changeset
956 strncpy(p, "ERR", 3);
68102
e2f96bd29252 Issue #8914: fix various warnings from the Clang static analyzer v254.
Brett Cannon <bcannon@gmail.com>
parents: 61466
diff changeset
957 /* p += 3; */
62910
5025ba0553b6 Revert temporary debugging commits (r82752, r82754).
Mark Dickinson <dickinsm@gmail.com>
parents: 62909
diff changeset
958 assert(0);
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
959 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
960 goto exit;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
961 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
962
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
963 /* The result must be finite (not inf or nan). */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
964 if (type)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
965 *type = Py_DTST_FINITE;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
966
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
967
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
968 /* We got digits back, format them. We may need to pad 'digits'
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
969 either on the left or right (or both) with extra zeros, so in
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
970 general the resulting string has the form
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
971
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
972 [<sign>]<zeros><digits><zeros>[<exponent>]
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
973
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
974 where either of the <zeros> pieces could be empty, and there's a
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
975 decimal point that could appear either in <digits> or in the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
976 leading or trailing <zeros>.
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
977
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
978 Imagine an infinite 'virtual' string vdigits, consisting of the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
979 string 'digits' (starting at index 0) padded on both the left and
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
980 right with infinite strings of zeros. We want to output a slice
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
981
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
982 vdigits[vdigits_start : vdigits_end]
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
983
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
984 of this virtual string. Thus if vdigits_start < 0 then we'll end
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
985 up producing some leading zeros; if vdigits_end > digits_len there
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
986 will be trailing zeros in the output. The next section of code
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
987 determines whether to use an exponent or not, figures out the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
988 position 'decpt' of the decimal point, and computes 'vdigits_start'
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
989 and 'vdigits_end'. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
990 vdigits_end = digits_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
991 switch (format_code) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
992 case 'e':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
993 use_exp = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
994 vdigits_end = precision;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
995 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
996 case 'f':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
997 vdigits_end = decpt + precision;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
998 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
999 case 'g':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1000 if (decpt <= -4 || decpt >
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1001 (add_dot_0_if_integer ? precision-1 : precision))
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1002 use_exp = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1003 if (use_alt_formatting)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1004 vdigits_end = precision;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1005 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1006 case 'r':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1007 /* convert to exponential format at 1e16. We used to convert
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1008 at 1e17, but that gives odd-looking results for some values
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1009 when a 16-digit 'shortest' repr is padded with bogus zeros.
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1010 For example, repr(2e16+8) would give 20000000000000010.0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1011 the true value is 20000000000000008.0. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1012 if (decpt <= -4 || decpt > 16)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1013 use_exp = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1014 break;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1015 default:
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1016 PyErr_BadInternalCall();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1017 goto exit;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1018 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1019
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1020 /* if using an exponent, reset decimal point position to 1 and adjust
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1021 exponent accordingly.*/
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1022 if (use_exp) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1023 exp = decpt - 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1024 decpt = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1025 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1026 /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1027 decpt < vdigits_end if add_dot_0_if_integer and no exponent */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1028 vdigits_start = decpt <= 0 ? decpt-1 : 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1029 if (!use_exp && add_dot_0_if_integer)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1030 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1031 else
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1032 vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1033
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1034 /* double check inequalities */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1035 assert(vdigits_start <= 0 &&
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1036 0 <= digits_len &&
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1037 digits_len <= vdigits_end);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1038 /* decimal point should be in (vdigits_start, vdigits_end] */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1039 assert(vdigits_start < decpt && decpt <= vdigits_end);
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1040
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1041 /* Compute an upper bound how much memory we need. This might be a few
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1042 chars too long, but no big deal. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1043 bufsize =
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1044 /* sign, decimal point and trailing 0 byte */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1045 3 +
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1046
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1047 /* total digit count (including zero padding on both sides) */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1048 (vdigits_end - vdigits_start) +
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1049
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1050 /* exponent "e+100", max 3 numerical digits */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1051 (use_exp ? 5 : 0);
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1052
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1053 /* Now allocate the memory and initialize p to point to the start of
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1054 it. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1055 buf = (char *)PyMem_Malloc(bufsize);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1056 if (buf == NULL) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1057 PyErr_NoMemory();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1058 goto exit;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1059 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1060 p = buf;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1061
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1062 /* Add a negative sign if negative, and a plus sign if non-negative
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1063 and always_add_sign is true. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1064 if (sign == 1)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1065 *p++ = '-';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1066 else if (always_add_sign)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1067 *p++ = '+';
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1068
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1069 /* note that exactly one of the three 'if' conditions is true,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1070 so we include exactly one decimal point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1071 /* Zero padding on left of digit string */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1072 if (decpt <= 0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1073 memset(p, '0', decpt-vdigits_start);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1074 p += decpt - vdigits_start;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1075 *p++ = '.';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1076 memset(p, '0', 0-decpt);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1077 p += 0-decpt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1078 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1079 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1080 memset(p, '0', 0-vdigits_start);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1081 p += 0 - vdigits_start;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1082 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1083
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1084 /* Digits, with included decimal point */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1085 if (0 < decpt && decpt <= digits_len) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1086 strncpy(p, digits, decpt-0);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1087 p += decpt-0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1088 *p++ = '.';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1089 strncpy(p, digits+decpt, digits_len-decpt);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1090 p += digits_len-decpt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1091 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1092 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1093 strncpy(p, digits, digits_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1094 p += digits_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1095 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1096
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1097 /* And zeros on the right */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1098 if (digits_len < decpt) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1099 memset(p, '0', decpt-digits_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1100 p += decpt-digits_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1101 *p++ = '.';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1102 memset(p, '0', vdigits_end-decpt);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1103 p += vdigits_end-decpt;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1104 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1105 else {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1106 memset(p, '0', vdigits_end-digits_len);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1107 p += vdigits_end-digits_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1108 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1109
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1110 /* Delete a trailing decimal pt unless using alternative formatting. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1111 if (p[-1] == '.' && !use_alt_formatting)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1112 p--;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1113
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1114 /* Now that we've done zero padding, add an exponent if needed. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1115 if (use_exp) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1116 *p++ = float_strings[OFS_E][0];
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1117 exp_len = sprintf(p, "%+.02d", exp);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1118 p += exp_len;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1119 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1120 exit:
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1121 if (buf) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1122 *p = '\0';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1123 /* It's too late if this fails, as we've already stepped on
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1124 memory that isn't ours. But it's an okay debugging test. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1125 assert(p-buf < bufsize);
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1126 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1127 if (digits)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1128 _Py_dg_freedtoa(digits);
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1129
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1130 return buf;
32305
13656d58d450 Patch #774665: Make Python LC_NUMERIC agnostic.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1131 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1132
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1133
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1134 PyAPI_FUNC(char *) PyOS_double_to_string(double val,
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1135 char format_code,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1136 int precision,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1137 int flags,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1138 int *type)
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1139 {
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1140 char **float_strings = lc_float_strings;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1141 int mode;
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1142
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1143 /* Validate format_code, and map upper and lower case. Compute the
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1144 mode and make any adjustments as needed. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1145 switch (format_code) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1146 /* exponent */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1147 case 'E':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1148 float_strings = uc_float_strings;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1149 format_code = 'e';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1150 /* Fall through. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1151 case 'e':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1152 mode = 2;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1153 precision++;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1154 break;
53190
d84ad973cde2 Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents: 53187
diff changeset
1155
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1156 /* fixed */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1157 case 'F':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1158 float_strings = uc_float_strings;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1159 format_code = 'f';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1160 /* Fall through. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1161 case 'f':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1162 mode = 3;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1163 break;
53190
d84ad973cde2 Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents: 53187
diff changeset
1164
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1165 /* general */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1166 case 'G':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1167 float_strings = uc_float_strings;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1168 format_code = 'g';
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1169 /* Fall through. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1170 case 'g':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1171 mode = 2;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1172 /* precision 0 makes no sense for 'g' format; interpret as 1 */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1173 if (precision == 0)
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1174 precision = 1;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1175 break;
53190
d84ad973cde2 Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents: 53187
diff changeset
1176
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1177 /* repr format */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1178 case 'r':
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1179 mode = 0;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1180 /* Supplied precision is unused, must be 0. */
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1181 if (precision != 0) {
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1182 PyErr_BadInternalCall();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1183 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1184 }
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1185 break;
53190
d84ad973cde2 Simplify PyOS_double_to_string.
Eric Smith <eric@trueblade.com>
parents: 53187
diff changeset
1186
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1187 default:
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1188 PyErr_BadInternalCall();
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1189 return NULL;
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1190 }
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1191
61467
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1192 return format_float_short(val, format_code, mode, precision,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1193 flags & Py_DTSF_SIGN,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1194 flags & Py_DTSF_ADD_DOT_0,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1195 flags & Py_DTSF_ALT,
f197407bdba2 Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58468
diff changeset
1196 float_strings, type);
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1197 }
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52773
diff changeset
1198 #endif /* ifdef PY_NO_SHORT_FLOAT_REPR */