ยปCore Development>Code coverage>Python/pystrtod.c

Python code coverage for Python/pystrtod.c

#countcontent
1n/a/* -*- Mode: C; c-file-style: "python" -*- */
2n/a
3n/a#include <Python.h>
4n/a#include <locale.h>
5n/a
6n/a/* Case-insensitive string match used for nan and inf detection; t should be
7n/a lower-case. Returns 1 for a successful match, 0 otherwise. */
8n/a
9n/astatic int
10n/acase_insensitive_match(const char *s, const char *t)
11n/a{
12n/a while(*t && Py_TOLOWER(*s) == *t) {
13n/a s++;
14n/a t++;
15n/a }
16n/a return *t ? 0 : 1;
17n/a}
18n/a
19n/a/* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or
20n/a "infinity", with an optional leading sign of "+" or "-". On success,
21n/a return the NaN or Infinity as a double and set *endptr to point just beyond
22n/a the successfully parsed portion of the string. On failure, return -1.0 and
23n/a set *endptr to point to the start of the string. */
24n/a
25n/a#ifndef PY_NO_SHORT_FLOAT_REPR
26n/a
27n/adouble
28n/a_Py_parse_inf_or_nan(const char *p, char **endptr)
29n/a{
30n/a double retval;
31n/a const char *s;
32n/a int negate = 0;
33n/a
34n/a s = p;
35n/a if (*s == '-') {
36n/a negate = 1;
37n/a s++;
38n/a }
39n/a else if (*s == '+') {
40n/a s++;
41n/a }
42n/a if (case_insensitive_match(s, "inf")) {
43n/a s += 3;
44n/a if (case_insensitive_match(s, "inity"))
45n/a s += 5;
46n/a retval = _Py_dg_infinity(negate);
47n/a }
48n/a else if (case_insensitive_match(s, "nan")) {
49n/a s += 3;
50n/a retval = _Py_dg_stdnan(negate);
51n/a }
52n/a else {
53n/a s = p;
54n/a retval = -1.0;
55n/a }
56n/a *endptr = (char *)s;
57n/a return retval;
58n/a}
59n/a
60n/a#else
61n/a
62n/adouble
63n/a_Py_parse_inf_or_nan(const char *p, char **endptr)
64n/a{
65n/a double retval;
66n/a const char *s;
67n/a int negate = 0;
68n/a
69n/a s = p;
70n/a if (*s == '-') {
71n/a negate = 1;
72n/a s++;
73n/a }
74n/a else if (*s == '+') {
75n/a s++;
76n/a }
77n/a if (case_insensitive_match(s, "inf")) {
78n/a s += 3;
79n/a if (case_insensitive_match(s, "inity"))
80n/a s += 5;
81n/a retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL;
82n/a }
83n/a#ifdef Py_NAN
84n/a else if (case_insensitive_match(s, "nan")) {
85n/a s += 3;
86n/a retval = negate ? -Py_NAN : Py_NAN;
87n/a }
88n/a#endif
89n/a else {
90n/a s = p;
91n/a retval = -1.0;
92n/a }
93n/a *endptr = (char *)s;
94n/a return retval;
95n/a}
96n/a
97n/a#endif
98n/a
99n/a/**
100n/a * _PyOS_ascii_strtod:
101n/a * @nptr: the string to convert to a numeric value.
102n/a * @endptr: if non-%NULL, it returns the character after
103n/a * the last character used in the conversion.
104n/a *
105n/a * Converts a string to a #gdouble value.
106n/a * This function behaves like the standard strtod() function
107n/a * does in the C locale. It does this without actually
108n/a * changing the current locale, since that would not be
109n/a * thread-safe.
110n/a *
111n/a * This function is typically used when reading configuration
112n/a * files or other non-user input that should be locale independent.
113n/a * To handle input from the user you should normally use the
114n/a * locale-sensitive system strtod() function.
115n/a *
116n/a * If the correct value would cause overflow, plus or minus %HUGE_VAL
117n/a * is returned (according to the sign of the value), and %ERANGE is
118n/a * stored in %errno. If the correct value would cause underflow,
119n/a * zero is returned and %ERANGE is stored in %errno.
120n/a * If memory allocation fails, %ENOMEM is stored in %errno.
121n/a *
122n/a * This function resets %errno before calling strtod() so that
123n/a * you can reliably detect overflow and underflow.
124n/a *
125n/a * Return value: the #gdouble value.
126n/a **/
127n/a
128n/a#ifndef PY_NO_SHORT_FLOAT_REPR
129n/a
130n/astatic double
131n/a_PyOS_ascii_strtod(const char *nptr, char **endptr)
132n/a{
133n/a double result;
134n/a _Py_SET_53BIT_PRECISION_HEADER;
135n/a
136n/a assert(nptr != NULL);
137n/a /* Set errno to zero, so that we can distinguish zero results
138n/a and underflows */
139n/a errno = 0;
140n/a
141n/a _Py_SET_53BIT_PRECISION_START;
142n/a result = _Py_dg_strtod(nptr, endptr);
143n/a _Py_SET_53BIT_PRECISION_END;
144n/a
145n/a if (*endptr == nptr)
146n/a /* string might represent an inf or nan */
147n/a result = _Py_parse_inf_or_nan(nptr, endptr);
148n/a
149n/a return result;
150n/a
151n/a}
152n/a
153n/a#else
154n/a
155n/a/*
156n/a Use system strtod; since strtod is locale aware, we may
157n/a have to first fix the decimal separator.
158n/a
159n/a Note that unlike _Py_dg_strtod, the system strtod may not always give
160n/a correctly rounded results.
161n/a*/
162n/a
163n/astatic double
164n/a_PyOS_ascii_strtod(const char *nptr, char **endptr)
165n/a{
166n/a char *fail_pos;
167n/a double val;
168n/a struct lconv *locale_data;
169n/a const char *decimal_point;
170n/a size_t decimal_point_len;
171n/a const char *p, *decimal_point_pos;
172n/a const char *end = NULL; /* Silence gcc */
173n/a const char *digits_pos = NULL;
174n/a int negate = 0;
175n/a
176n/a assert(nptr != NULL);
177n/a
178n/a fail_pos = NULL;
179n/a
180n/a locale_data = localeconv();
181n/a decimal_point = locale_data->decimal_point;
182n/a decimal_point_len = strlen(decimal_point);
183n/a
184n/a assert(decimal_point_len != 0);
185n/a
186n/a decimal_point_pos = NULL;
187n/a
188n/a /* Parse infinities and nans */
189n/a val = _Py_parse_inf_or_nan(nptr, endptr);
190n/a if (*endptr != nptr)
191n/a return val;
192n/a
193n/a /* Set errno to zero, so that we can distinguish zero results
194n/a and underflows */
195n/a errno = 0;
196n/a
197n/a /* We process the optional sign manually, then pass the remainder to
198n/a the system strtod. This ensures that the result of an underflow
199n/a has the correct sign. (bug #1725) */
200n/a p = nptr;
201n/a /* Process leading sign, if present */
202n/a if (*p == '-') {
203n/a negate = 1;
204n/a p++;
205n/a }
206n/a else if (*p == '+') {
207n/a p++;
208n/a }
209n/a
210n/a /* Some platform strtods accept hex floats; Python shouldn't (at the
211n/a moment), so we check explicitly for strings starting with '0x'. */
212n/a if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X'))
213n/a goto invalid_string;
214n/a
215n/a /* Check that what's left begins with a digit or decimal point */
216n/a if (!Py_ISDIGIT(*p) && *p != '.')
217n/a goto invalid_string;
218n/a
219n/a digits_pos = p;
220n/a if (decimal_point[0] != '.' ||
221n/a decimal_point[1] != 0)
222n/a {
223n/a /* Look for a '.' in the input; if present, it'll need to be
224n/a swapped for the current locale's decimal point before we
225n/a call strtod. On the other hand, if we find the current
226n/a locale's decimal point then the input is invalid. */
227n/a while (Py_ISDIGIT(*p))
228n/a p++;
229n/a
230n/a if (*p == '.')
231n/a {
232n/a decimal_point_pos = p++;
233n/a
234n/a /* locate end of number */
235n/a while (Py_ISDIGIT(*p))
236n/a p++;
237n/a
238n/a if (*p == 'e' || *p == 'E')
239n/a p++;
240n/a if (*p == '+' || *p == '-')
241n/a p++;
242n/a while (Py_ISDIGIT(*p))
243n/a p++;
244n/a end = p;
245n/a }
246n/a else if (strncmp(p, decimal_point, decimal_point_len) == 0)
247n/a /* Python bug #1417699 */
248n/a goto invalid_string;
249n/a /* For the other cases, we need not convert the decimal
250n/a point */
251n/a }
252n/a
253n/a if (decimal_point_pos) {
254n/a char *copy, *c;
255n/a /* Create a copy of the input, with the '.' converted to the
256n/a locale-specific decimal point */
257n/a copy = (char *)PyMem_MALLOC(end - digits_pos +
258n/a 1 + decimal_point_len);
259n/a if (copy == NULL) {
260n/a *endptr = (char *)nptr;
261n/a errno = ENOMEM;
262n/a return val;
263n/a }
264n/a
265n/a c = copy;
266n/a memcpy(c, digits_pos, decimal_point_pos - digits_pos);
267n/a c += decimal_point_pos - digits_pos;
268n/a memcpy(c, decimal_point, decimal_point_len);
269n/a c += decimal_point_len;
270n/a memcpy(c, decimal_point_pos + 1,
271n/a end - (decimal_point_pos + 1));
272n/a c += end - (decimal_point_pos + 1);
273n/a *c = 0;
274n/a
275n/a val = strtod(copy, &fail_pos);
276n/a
277n/a if (fail_pos)
278n/a {
279n/a if (fail_pos > decimal_point_pos)
280n/a fail_pos = (char *)digits_pos +
281n/a (fail_pos - copy) -
282n/a (decimal_point_len - 1);
283n/a else
284n/a fail_pos = (char *)digits_pos +
285n/a (fail_pos - copy);
286n/a }
287n/a
288n/a PyMem_FREE(copy);
289n/a
290n/a }
291n/a else {
292n/a val = strtod(digits_pos, &fail_pos);
293n/a }
294n/a
295n/a if (fail_pos == digits_pos)
296n/a goto invalid_string;
297n/a
298n/a if (negate && fail_pos != nptr)
299n/a val = -val;
300n/a *endptr = fail_pos;
301n/a
302n/a return val;
303n/a
304n/a invalid_string:
305n/a *endptr = (char*)nptr;
306n/a errno = EINVAL;
307n/a return -1.0;
308n/a}
309n/a
310n/a#endif
311n/a
312n/a/* PyOS_string_to_double converts a null-terminated byte string s (interpreted
313n/a as a string of ASCII characters) to a float. The string should not have
314n/a leading or trailing whitespace. The conversion is independent of the
315n/a current locale.
316n/a
317n/a If endptr is NULL, try to convert the whole string. Raise ValueError and
318n/a return -1.0 if the string is not a valid representation of a floating-point
319n/a number.
320n/a
321n/a If endptr is non-NULL, try to convert as much of the string as possible.
322n/a If no initial segment of the string is the valid representation of a
323n/a floating-point number then *endptr is set to point to the beginning of the
324n/a string, -1.0 is returned and again ValueError is raised.
325n/a
326n/a On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
327n/a if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python
328n/a exception is raised. Otherwise, overflow_exception should point to
329n/a a Python exception, this exception will be raised, -1.0 will be returned,
330n/a and *endptr will point just past the end of the converted value.
331n/a
332n/a If any other failure occurs (for example lack of memory), -1.0 is returned
333n/a and the appropriate Python exception will have been set.
334n/a*/
335n/a
336n/adouble
337n/aPyOS_string_to_double(const char *s,
338n/a char **endptr,
339n/a PyObject *overflow_exception)
340n/a{
341n/a double x, result=-1.0;
342n/a char *fail_pos;
343n/a
344n/a errno = 0;
345n/a PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0)
346n/a x = _PyOS_ascii_strtod(s, &fail_pos);
347n/a PyFPE_END_PROTECT(x)
348n/a
349n/a if (errno == ENOMEM) {
350n/a PyErr_NoMemory();
351n/a fail_pos = (char *)s;
352n/a }
353n/a else if (!endptr && (fail_pos == s || *fail_pos != '\0'))
354n/a PyErr_Format(PyExc_ValueError,
355n/a "could not convert string to float: "
356n/a "%.200s", s);
357n/a else if (fail_pos == s)
358n/a PyErr_Format(PyExc_ValueError,
359n/a "could not convert string to float: "
360n/a "%.200s", s);
361n/a else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)
362n/a PyErr_Format(overflow_exception,
363n/a "value too large to convert to float: "
364n/a "%.200s", s);
365n/a else
366n/a result = x;
367n/a
368n/a if (endptr != NULL)
369n/a *endptr = fail_pos;
370n/a return result;
371n/a}
372n/a
373n/a/* Remove underscores that follow the underscore placement rule from
374n/a the string and then call the `innerfunc` function on the result.
375n/a It should return a new object or NULL on exception.
376n/a
377n/a `what` is used for the error message emitted when underscores are detected
378n/a that don't follow the rule. `arg` is an opaque pointer passed to the inner
379n/a function.
380n/a
381n/a This is used to implement underscore-agnostic conversion for floats
382n/a and complex numbers.
383n/a*/
384n/aPyObject *
385n/a_Py_string_to_number_with_underscores(
386n/a const char *s, Py_ssize_t orig_len, const char *what, PyObject *obj, void *arg,
387n/a PyObject *(*innerfunc)(const char *, Py_ssize_t, void *))
388n/a{
389n/a char prev;
390n/a const char *p, *last;
391n/a char *dup, *end;
392n/a PyObject *result;
393n/a
394n/a if (strchr(s, '_') == NULL) {
395n/a return innerfunc(s, orig_len, arg);
396n/a }
397n/a
398n/a dup = PyMem_Malloc(orig_len + 1);
399n/a end = dup;
400n/a prev = '\0';
401n/a last = s + orig_len;
402n/a for (p = s; *p; p++) {
403n/a if (*p == '_') {
404n/a /* Underscores are only allowed after digits. */
405n/a if (!(prev >= '0' && prev <= '9')) {
406n/a goto error;
407n/a }
408n/a }
409n/a else {
410n/a *end++ = *p;
411n/a /* Underscores are only allowed before digits. */
412n/a if (prev == '_' && !(*p >= '0' && *p <= '9')) {
413n/a goto error;
414n/a }
415n/a }
416n/a prev = *p;
417n/a }
418n/a /* Underscores are not allowed at the end. */
419n/a if (prev == '_') {
420n/a goto error;
421n/a }
422n/a /* No embedded NULs allowed. */
423n/a if (p != last) {
424n/a goto error;
425n/a }
426n/a *end = '\0';
427n/a result = innerfunc(dup, end - dup, arg);
428n/a PyMem_Free(dup);
429n/a return result;
430n/a
431n/a error:
432n/a PyMem_Free(dup);
433n/a PyErr_Format(PyExc_ValueError,
434n/a "could not convert string to %s: "
435n/a "%R", what, obj);
436n/a return NULL;
437n/a}
438n/a
439n/a#ifdef PY_NO_SHORT_FLOAT_REPR
440n/a
441n/a/* Given a string that may have a decimal point in the current
442n/a locale, change it back to a dot. Since the string cannot get
443n/a longer, no need for a maximum buffer size parameter. */
444n/aPy_LOCAL_INLINE(void)
445n/achange_decimal_from_locale_to_dot(char* buffer)
446n/a{
447n/a struct lconv *locale_data = localeconv();
448n/a const char *decimal_point = locale_data->decimal_point;
449n/a
450n/a if (decimal_point[0] != '.' || decimal_point[1] != 0) {
451n/a size_t decimal_point_len = strlen(decimal_point);
452n/a
453n/a if (*buffer == '+' || *buffer == '-')
454n/a buffer++;
455n/a while (Py_ISDIGIT(*buffer))
456n/a buffer++;
457n/a if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
458n/a *buffer = '.';
459n/a buffer++;
460n/a if (decimal_point_len > 1) {
461n/a /* buffer needs to get smaller */
462n/a size_t rest_len = strlen(buffer +
463n/a (decimal_point_len - 1));
464n/a memmove(buffer,
465n/a buffer + (decimal_point_len - 1),
466n/a rest_len);
467n/a buffer[rest_len] = 0;
468n/a }
469n/a }
470n/a }
471n/a}
472n/a
473n/a
474n/a/* From the C99 standard, section 7.19.6:
475n/aThe exponent always contains at least two digits, and only as many more digits
476n/aas necessary to represent the exponent.
477n/a*/
478n/a#define MIN_EXPONENT_DIGITS 2
479n/a
480n/a/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS
481n/a in length. */
482n/aPy_LOCAL_INLINE(void)
483n/aensure_minimum_exponent_length(char* buffer, size_t buf_size)
484n/a{
485n/a char *p = strpbrk(buffer, "eE");
486n/a if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
487n/a char *start = p + 2;
488n/a int exponent_digit_cnt = 0;
489n/a int leading_zero_cnt = 0;
490n/a int in_leading_zeros = 1;
491n/a int significant_digit_cnt;
492n/a
493n/a /* Skip over the exponent and the sign. */
494n/a p += 2;
495n/a
496n/a /* Find the end of the exponent, keeping track of leading
497n/a zeros. */
498n/a while (*p && Py_ISDIGIT(*p)) {
499n/a if (in_leading_zeros && *p == '0')
500n/a ++leading_zero_cnt;
501n/a if (*p != '0')
502n/a in_leading_zeros = 0;
503n/a ++p;
504n/a ++exponent_digit_cnt;
505n/a }
506n/a
507n/a significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
508n/a if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
509n/a /* If there are 2 exactly digits, we're done,
510n/a regardless of what they contain */
511n/a }
512n/a else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
513n/a int extra_zeros_cnt;
514n/a
515n/a /* There are more than 2 digits in the exponent. See
516n/a if we can delete some of the leading zeros */
517n/a if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
518n/a significant_digit_cnt = MIN_EXPONENT_DIGITS;
519n/a extra_zeros_cnt = exponent_digit_cnt -
520n/a significant_digit_cnt;
521n/a
522n/a /* Delete extra_zeros_cnt worth of characters from the
523n/a front of the exponent */
524n/a assert(extra_zeros_cnt >= 0);
525n/a
526n/a /* Add one to significant_digit_cnt to copy the
527n/a trailing 0 byte, thus setting the length */
528n/a memmove(start,
529n/a start + extra_zeros_cnt,
530n/a significant_digit_cnt + 1);
531n/a }
532n/a else {
533n/a /* If there are fewer than 2 digits, add zeros
534n/a until there are 2, if there's enough room */
535n/a int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
536n/a if (start + zeros + exponent_digit_cnt + 1
537n/a < buffer + buf_size) {
538n/a memmove(start + zeros, start,
539n/a exponent_digit_cnt + 1);
540n/a memset(start, '0', zeros);
541n/a }
542n/a }
543n/a }
544n/a}
545n/a
546n/a/* Remove trailing zeros after the decimal point from a numeric string; also
547n/a remove the decimal point if all digits following it are zero. The numeric
548n/a string must end in '\0', and should not have any leading or trailing
549n/a whitespace. Assumes that the decimal point is '.'. */
550n/aPy_LOCAL_INLINE(void)
551n/aremove_trailing_zeros(char *buffer)
552n/a{
553n/a char *old_fraction_end, *new_fraction_end, *end, *p;
554n/a
555n/a p = buffer;
556n/a if (*p == '-' || *p == '+')
557n/a /* Skip leading sign, if present */
558n/a ++p;
559n/a while (Py_ISDIGIT(*p))
560n/a ++p;
561n/a
562n/a /* if there's no decimal point there's nothing to do */
563n/a if (*p++ != '.')
564n/a return;
565n/a
566n/a /* scan any digits after the point */
567n/a while (Py_ISDIGIT(*p))
568n/a ++p;
569n/a old_fraction_end = p;
570n/a
571n/a /* scan up to ending '\0' */
572n/a while (*p != '\0')
573n/a p++;
574n/a /* +1 to make sure that we move the null byte as well */
575n/a end = p+1;
576n/a
577n/a /* scan back from fraction_end, looking for removable zeros */
578n/a p = old_fraction_end;
579n/a while (*(p-1) == '0')
580n/a --p;
581n/a /* and remove point if we've got that far */
582n/a if (*(p-1) == '.')
583n/a --p;
584n/a new_fraction_end = p;
585n/a
586n/a memmove(new_fraction_end, old_fraction_end, end-old_fraction_end);
587n/a}
588n/a
589n/a/* Ensure that buffer has a decimal point in it. The decimal point will not
590n/a be in the current locale, it will always be '.'. Don't add a decimal point
591n/a if an exponent is present. Also, convert to exponential notation where
592n/a adding a '.0' would produce too many significant digits (see issue 5864).
593n/a
594n/a Returns a pointer to the fixed buffer, or NULL on failure.
595n/a*/
596n/aPy_LOCAL_INLINE(char *)
597n/aensure_decimal_point(char* buffer, size_t buf_size, int precision)
598n/a{
599n/a int digit_count, insert_count = 0, convert_to_exp = 0;
600n/a char *chars_to_insert, *digits_start;
601n/a
602n/a /* search for the first non-digit character */
603n/a char *p = buffer;
604n/a if (*p == '-' || *p == '+')
605n/a /* Skip leading sign, if present. I think this could only
606n/a ever be '-', but it can't hurt to check for both. */
607n/a ++p;
608n/a digits_start = p;
609n/a while (*p && Py_ISDIGIT(*p))
610n/a ++p;
611n/a digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int);
612n/a
613n/a if (*p == '.') {
614n/a if (Py_ISDIGIT(*(p+1))) {
615n/a /* Nothing to do, we already have a decimal
616n/a point and a digit after it */
617n/a }
618n/a else {
619n/a /* We have a decimal point, but no following
620n/a digit. Insert a zero after the decimal. */
621n/a /* can't ever get here via PyOS_double_to_string */
622n/a assert(precision == -1);
623n/a ++p;
624n/a chars_to_insert = "0";
625n/a insert_count = 1;
626n/a }
627n/a }
628n/a else if (!(*p == 'e' || *p == 'E')) {
629n/a /* Don't add ".0" if we have an exponent. */
630n/a if (digit_count == precision) {
631n/a /* issue 5864: don't add a trailing .0 in the case
632n/a where the '%g'-formatted result already has as many
633n/a significant digits as were requested. Switch to
634n/a exponential notation instead. */
635n/a convert_to_exp = 1;
636n/a /* no exponent, no point, and we shouldn't land here
637n/a for infs and nans, so we must be at the end of the
638n/a string. */
639n/a assert(*p == '\0');
640n/a }
641n/a else {
642n/a assert(precision == -1 || digit_count < precision);
643n/a chars_to_insert = ".0";
644n/a insert_count = 2;
645n/a }
646n/a }
647n/a if (insert_count) {
648n/a size_t buf_len = strlen(buffer);
649n/a if (buf_len + insert_count + 1 >= buf_size) {
650n/a /* If there is not enough room in the buffer
651n/a for the additional text, just skip it. It's
652n/a not worth generating an error over. */
653n/a }
654n/a else {
655n/a memmove(p + insert_count, p,
656n/a buffer + strlen(buffer) - p + 1);
657n/a memcpy(p, chars_to_insert, insert_count);
658n/a }
659n/a }
660n/a if (convert_to_exp) {
661n/a int written;
662n/a size_t buf_avail;
663n/a p = digits_start;
664n/a /* insert decimal point */
665n/a assert(digit_count >= 1);
666n/a memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */
667n/a p[1] = '.';
668n/a p += digit_count+1;
669n/a assert(p <= buf_size+buffer);
670n/a buf_avail = buf_size+buffer-p;
671n/a if (buf_avail == 0)
672n/a return NULL;
673n/a /* Add exponent. It's okay to use lower case 'e': we only
674n/a arrive here as a result of using the empty format code or
675n/a repr/str builtins and those never want an upper case 'E' */
676n/a written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1);
677n/a if (!(0 <= written &&
678n/a written < Py_SAFE_DOWNCAST(buf_avail, size_t, int)))
679n/a /* output truncated, or something else bad happened */
680n/a return NULL;
681n/a remove_trailing_zeros(buffer);
682n/a }
683n/a return buffer;
684n/a}
685n/a
686n/a/* see FORMATBUFLEN in unicodeobject.c */
687n/a#define FLOAT_FORMATBUFLEN 120
688n/a
689n/a/**
690n/a * _PyOS_ascii_formatd:
691n/a * @buffer: A buffer to place the resulting string in
692n/a * @buf_size: The length of the buffer.
693n/a * @format: The printf()-style format to use for the
694n/a * code to use for converting.
695n/a * @d: The #gdouble to convert
696n/a * @precision: The precision to use when formatting.
697n/a *
698n/a * Converts a #gdouble to a string, using the '.' as
699n/a * decimal point. To format the number you pass in
700n/a * a printf()-style format string. Allowed conversion
701n/a * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'.
702n/a *
703n/a * 'Z' is the same as 'g', except it always has a decimal and
704n/a * at least one digit after the decimal.
705n/a *
706n/a * Return value: The pointer to the buffer with the converted string.
707n/a * On failure returns NULL but does not set any Python exception.
708n/a **/
709n/astatic char *
710n/a_PyOS_ascii_formatd(char *buffer,
711n/a size_t buf_size,
712n/a const char *format,
713n/a double d,
714n/a int precision)
715n/a{
716n/a char format_char;
717n/a size_t format_len = strlen(format);
718n/a
719n/a /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but
720n/a also with at least one character past the decimal. */
721n/a char tmp_format[FLOAT_FORMATBUFLEN];
722n/a
723n/a /* The last character in the format string must be the format char */
724n/a format_char = format[format_len - 1];
725n/a
726n/a if (format[0] != '%')
727n/a return NULL;
728n/a
729n/a /* I'm not sure why this test is here. It's ensuring that the format
730n/a string after the first character doesn't have a single quote, a
731n/a lowercase l, or a percent. This is the reverse of the commented-out
732n/a test about 10 lines ago. */
733n/a if (strpbrk(format + 1, "'l%"))
734n/a return NULL;
735n/a
736n/a /* Also curious about this function is that it accepts format strings
737n/a like "%xg", which are invalid for floats. In general, the
738n/a interface to this function is not very good, but changing it is
739n/a difficult because it's a public API. */
740n/a
741n/a if (!(format_char == 'e' || format_char == 'E' ||
742n/a format_char == 'f' || format_char == 'F' ||
743n/a format_char == 'g' || format_char == 'G' ||
744n/a format_char == 'Z'))
745n/a return NULL;
746n/a
747n/a /* Map 'Z' format_char to 'g', by copying the format string and
748n/a replacing the final char with a 'g' */
749n/a if (format_char == 'Z') {
750n/a if (format_len + 1 >= sizeof(tmp_format)) {
751n/a /* The format won't fit in our copy. Error out. In
752n/a practice, this will never happen and will be
753n/a detected by returning NULL */
754n/a return NULL;
755n/a }
756n/a strcpy(tmp_format, format);
757n/a tmp_format[format_len - 1] = 'g';
758n/a format = tmp_format;
759n/a }
760n/a
761n/a
762n/a /* Have PyOS_snprintf do the hard work */
763n/a PyOS_snprintf(buffer, buf_size, format, d);
764n/a
765n/a /* Do various fixups on the return string */
766n/a
767n/a /* Get the current locale, and find the decimal point string.
768n/a Convert that string back to a dot. */
769n/a change_decimal_from_locale_to_dot(buffer);
770n/a
771n/a /* If an exponent exists, ensure that the exponent is at least
772n/a MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
773n/a for the extra zeros. Also, if there are more than
774n/a MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
775n/a back to MIN_EXPONENT_DIGITS */
776n/a ensure_minimum_exponent_length(buffer, buf_size);
777n/a
778n/a /* If format_char is 'Z', make sure we have at least one character
779n/a after the decimal point (and make sure we have a decimal point);
780n/a also switch to exponential notation in some edge cases where the
781n/a extra character would produce more significant digits that we
782n/a really want. */
783n/a if (format_char == 'Z')
784n/a buffer = ensure_decimal_point(buffer, buf_size, precision);
785n/a
786n/a return buffer;
787n/a}
788n/a
789n/a/* The fallback code to use if _Py_dg_dtoa is not available. */
790n/a
791n/aPyAPI_FUNC(char *) PyOS_double_to_string(double val,
792n/a char format_code,
793n/a int precision,
794n/a int flags,
795n/a int *type)
796n/a{
797n/a char format[32];
798n/a Py_ssize_t bufsize;
799n/a char *buf;
800n/a int t, exp;
801n/a int upper = 0;
802n/a
803n/a /* Validate format_code, and map upper and lower case */
804n/a switch (format_code) {
805n/a case 'e': /* exponent */
806n/a case 'f': /* fixed */
807n/a case 'g': /* general */
808n/a break;
809n/a case 'E':
810n/a upper = 1;
811n/a format_code = 'e';
812n/a break;
813n/a case 'F':
814n/a upper = 1;
815n/a format_code = 'f';
816n/a break;
817n/a case 'G':
818n/a upper = 1;
819n/a format_code = 'g';
820n/a break;
821n/a case 'r': /* repr format */
822n/a /* Supplied precision is unused, must be 0. */
823n/a if (precision != 0) {
824n/a PyErr_BadInternalCall();
825n/a return NULL;
826n/a }
827n/a /* The repr() precision (17 significant decimal digits) is the
828n/a minimal number that is guaranteed to have enough precision
829n/a so that if the number is read back in the exact same binary
830n/a value is recreated. This is true for IEEE floating point
831n/a by design, and also happens to work for all other modern
832n/a hardware. */
833n/a precision = 17;
834n/a format_code = 'g';
835n/a break;
836n/a default:
837n/a PyErr_BadInternalCall();
838n/a return NULL;
839n/a }
840n/a
841n/a /* Here's a quick-and-dirty calculation to figure out how big a buffer
842n/a we need. In general, for a finite float we need:
843n/a
844n/a 1 byte for each digit of the decimal significand, and
845n/a
846n/a 1 for a possible sign
847n/a 1 for a possible decimal point
848n/a 2 for a possible [eE][+-]
849n/a 1 for each digit of the exponent; if we allow 19 digits
850n/a total then we're safe up to exponents of 2**63.
851n/a 1 for the trailing nul byte
852n/a
853n/a This gives a total of 24 + the number of digits in the significand,
854n/a and the number of digits in the significand is:
855n/a
856n/a for 'g' format: at most precision, except possibly
857n/a when precision == 0, when it's 1.
858n/a for 'e' format: precision+1
859n/a for 'f' format: precision digits after the point, at least 1
860n/a before. To figure out how many digits appear before the point
861n/a we have to examine the size of the number. If fabs(val) < 1.0
862n/a then there will be only one digit before the point. If
863n/a fabs(val) >= 1.0, then there are at most
864n/a
865n/a 1+floor(log10(ceiling(fabs(val))))
866n/a
867n/a digits before the point (where the 'ceiling' allows for the
868n/a possibility that the rounding rounds the integer part of val
869n/a up). A safe upper bound for the above quantity is
870n/a 1+floor(exp/3), where exp is the unique integer such that 0.5
871n/a <= fabs(val)/2**exp < 1.0. This exp can be obtained from
872n/a frexp.
873n/a
874n/a So we allow room for precision+1 digits for all formats, plus an
875n/a extra floor(exp/3) digits for 'f' format.
876n/a
877n/a */
878n/a
879n/a if (Py_IS_NAN(val) || Py_IS_INFINITY(val))
880n/a /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */
881n/a bufsize = 5;
882n/a else {
883n/a bufsize = 25 + precision;
884n/a if (format_code == 'f' && fabs(val) >= 1.0) {
885n/a frexp(val, &exp);
886n/a bufsize += exp/3;
887n/a }
888n/a }
889n/a
890n/a buf = PyMem_Malloc(bufsize);
891n/a if (buf == NULL) {
892n/a PyErr_NoMemory();
893n/a return NULL;
894n/a }
895n/a
896n/a /* Handle nan and inf. */
897n/a if (Py_IS_NAN(val)) {
898n/a strcpy(buf, "nan");
899n/a t = Py_DTST_NAN;
900n/a } else if (Py_IS_INFINITY(val)) {
901n/a if (copysign(1., val) == 1.)
902n/a strcpy(buf, "inf");
903n/a else
904n/a strcpy(buf, "-inf");
905n/a t = Py_DTST_INFINITE;
906n/a } else {
907n/a t = Py_DTST_FINITE;
908n/a if (flags & Py_DTSF_ADD_DOT_0)
909n/a format_code = 'Z';
910n/a
911n/a PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
912n/a (flags & Py_DTSF_ALT ? "#" : ""), precision,
913n/a format_code);
914n/a _PyOS_ascii_formatd(buf, bufsize, format, val, precision);
915n/a }
916n/a
917n/a /* Add sign when requested. It's convenient (esp. when formatting
918n/a complex numbers) to include a sign even for inf and nan. */
919n/a if (flags & Py_DTSF_SIGN && buf[0] != '-') {
920n/a size_t len = strlen(buf);
921n/a /* the bufsize calculations above should ensure that we've got
922n/a space to add a sign */
923n/a assert((size_t)bufsize >= len+2);
924n/a memmove(buf+1, buf, len+1);
925n/a buf[0] = '+';
926n/a }
927n/a if (upper) {
928n/a /* Convert to upper case. */
929n/a char *p1;
930n/a for (p1 = buf; *p1; p1++)
931n/a *p1 = Py_TOUPPER(*p1);
932n/a }
933n/a
934n/a if (type)
935n/a *type = t;
936n/a return buf;
937n/a}
938n/a
939n/a#else
940n/a
941n/a/* _Py_dg_dtoa is available. */
942n/a
943n/a/* I'm using a lookup table here so that I don't have to invent a non-locale
944n/a specific way to convert to uppercase */
945n/a#define OFS_INF 0
946n/a#define OFS_NAN 1
947n/a#define OFS_E 2
948n/a
949n/a/* The lengths of these are known to the code below, so don't change them */
950n/astatic const char * const lc_float_strings[] = {
951n/a "inf",
952n/a "nan",
953n/a "e",
954n/a};
955n/astatic const char * const uc_float_strings[] = {
956n/a "INF",
957n/a "NAN",
958n/a "E",
959n/a};
960n/a
961n/a
962n/a/* Convert a double d to a string, and return a PyMem_Malloc'd block of
963n/a memory contain the resulting string.
964n/a
965n/a Arguments:
966n/a d is the double to be converted
967n/a format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g'
968n/a correspond to '%e', '%f' and '%g'; 'r' corresponds to repr.
969n/a mode is one of '0', '2' or '3', and is completely determined by
970n/a format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0.
971n/a precision is the desired precision
972n/a always_add_sign is nonzero if a '+' sign should be included for positive
973n/a numbers
974n/a add_dot_0_if_integer is nonzero if integers in non-exponential form
975n/a should have ".0" added. Only applies to format codes 'r' and 'g'.
976n/a use_alt_formatting is nonzero if alternative formatting should be
977n/a used. Only applies to format codes 'e', 'f' and 'g'. For code 'g',
978n/a at most one of use_alt_formatting and add_dot_0_if_integer should
979n/a be nonzero.
980n/a type, if non-NULL, will be set to one of these constants to identify
981n/a the type of the 'd' argument:
982n/a Py_DTST_FINITE
983n/a Py_DTST_INFINITE
984n/a Py_DTST_NAN
985n/a
986n/a Returns a PyMem_Malloc'd block of memory containing the resulting string,
987n/a or NULL on error. If NULL is returned, the Python error has been set.
988n/a */
989n/a
990n/astatic char *
991n/aformat_float_short(double d, char format_code,
992n/a int mode, int precision,
993n/a int always_add_sign, int add_dot_0_if_integer,
994n/a int use_alt_formatting, const char * const *float_strings,
995n/a int *type)
996n/a{
997n/a char *buf = NULL;
998n/a char *p = NULL;
999n/a Py_ssize_t bufsize = 0;
1000n/a char *digits, *digits_end;
1001n/a int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
1002n/a Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
1003n/a _Py_SET_53BIT_PRECISION_HEADER;
1004n/a
1005n/a /* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
1006n/a Must be matched by a call to _Py_dg_freedtoa. */
1007n/a _Py_SET_53BIT_PRECISION_START;
1008n/a digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
1009n/a &digits_end);
1010n/a _Py_SET_53BIT_PRECISION_END;
1011n/a
1012n/a decpt = (Py_ssize_t)decpt_as_int;
1013n/a if (digits == NULL) {
1014n/a /* The only failure mode is no memory. */
1015n/a PyErr_NoMemory();
1016n/a goto exit;
1017n/a }
1018n/a assert(digits_end != NULL && digits_end >= digits);
1019n/a digits_len = digits_end - digits;
1020n/a
1021n/a if (digits_len && !Py_ISDIGIT(digits[0])) {
1022n/a /* Infinities and nans here; adapt Gay's output,
1023n/a so convert Infinity to inf and NaN to nan, and
1024n/a ignore sign of nan. Then return. */
1025n/a
1026n/a /* ignore the actual sign of a nan */
1027n/a if (digits[0] == 'n' || digits[0] == 'N')
1028n/a sign = 0;
1029n/a
1030n/a /* We only need 5 bytes to hold the result "+inf\0" . */
1031n/a bufsize = 5; /* Used later in an assert. */
1032n/a buf = (char *)PyMem_Malloc(bufsize);
1033n/a if (buf == NULL) {
1034n/a PyErr_NoMemory();
1035n/a goto exit;
1036n/a }
1037n/a p = buf;
1038n/a
1039n/a if (sign == 1) {
1040n/a *p++ = '-';
1041n/a }
1042n/a else if (always_add_sign) {
1043n/a *p++ = '+';
1044n/a }
1045n/a if (digits[0] == 'i' || digits[0] == 'I') {
1046n/a strncpy(p, float_strings[OFS_INF], 3);
1047n/a p += 3;
1048n/a
1049n/a if (type)
1050n/a *type = Py_DTST_INFINITE;
1051n/a }
1052n/a else if (digits[0] == 'n' || digits[0] == 'N') {
1053n/a strncpy(p, float_strings[OFS_NAN], 3);
1054n/a p += 3;
1055n/a
1056n/a if (type)
1057n/a *type = Py_DTST_NAN;
1058n/a }
1059n/a else {
1060n/a /* shouldn't get here: Gay's code should always return
1061n/a something starting with a digit, an 'I', or 'N' */
1062n/a strncpy(p, "ERR", 3);
1063n/a /* p += 3; */
1064n/a assert(0);
1065n/a }
1066n/a goto exit;
1067n/a }
1068n/a
1069n/a /* The result must be finite (not inf or nan). */
1070n/a if (type)
1071n/a *type = Py_DTST_FINITE;
1072n/a
1073n/a
1074n/a /* We got digits back, format them. We may need to pad 'digits'
1075n/a either on the left or right (or both) with extra zeros, so in
1076n/a general the resulting string has the form
1077n/a
1078n/a [<sign>]<zeros><digits><zeros>[<exponent>]
1079n/a
1080n/a where either of the <zeros> pieces could be empty, and there's a
1081n/a decimal point that could appear either in <digits> or in the
1082n/a leading or trailing <zeros>.
1083n/a
1084n/a Imagine an infinite 'virtual' string vdigits, consisting of the
1085n/a string 'digits' (starting at index 0) padded on both the left and
1086n/a right with infinite strings of zeros. We want to output a slice
1087n/a
1088n/a vdigits[vdigits_start : vdigits_end]
1089n/a
1090n/a of this virtual string. Thus if vdigits_start < 0 then we'll end
1091n/a up producing some leading zeros; if vdigits_end > digits_len there
1092n/a will be trailing zeros in the output. The next section of code
1093n/a determines whether to use an exponent or not, figures out the
1094n/a position 'decpt' of the decimal point, and computes 'vdigits_start'
1095n/a and 'vdigits_end'. */
1096n/a vdigits_end = digits_len;
1097n/a switch (format_code) {
1098n/a case 'e':
1099n/a use_exp = 1;
1100n/a vdigits_end = precision;
1101n/a break;
1102n/a case 'f':
1103n/a vdigits_end = decpt + precision;
1104n/a break;
1105n/a case 'g':
1106n/a if (decpt <= -4 || decpt >
1107n/a (add_dot_0_if_integer ? precision-1 : precision))
1108n/a use_exp = 1;
1109n/a if (use_alt_formatting)
1110n/a vdigits_end = precision;
1111n/a break;
1112n/a case 'r':
1113n/a /* convert to exponential format at 1e16. We used to convert
1114n/a at 1e17, but that gives odd-looking results for some values
1115n/a when a 16-digit 'shortest' repr is padded with bogus zeros.
1116n/a For example, repr(2e16+8) would give 20000000000000010.0;
1117n/a the true value is 20000000000000008.0. */
1118n/a if (decpt <= -4 || decpt > 16)
1119n/a use_exp = 1;
1120n/a break;
1121n/a default:
1122n/a PyErr_BadInternalCall();
1123n/a goto exit;
1124n/a }
1125n/a
1126n/a /* if using an exponent, reset decimal point position to 1 and adjust
1127n/a exponent accordingly.*/
1128n/a if (use_exp) {
1129n/a exp = (int)decpt - 1;
1130n/a decpt = 1;
1131n/a }
1132n/a /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start <
1133n/a decpt < vdigits_end if add_dot_0_if_integer and no exponent */
1134n/a vdigits_start = decpt <= 0 ? decpt-1 : 0;
1135n/a if (!use_exp && add_dot_0_if_integer)
1136n/a vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
1137n/a else
1138n/a vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
1139n/a
1140n/a /* double check inequalities */
1141n/a assert(vdigits_start <= 0 &&
1142n/a 0 <= digits_len &&
1143n/a digits_len <= vdigits_end);
1144n/a /* decimal point should be in (vdigits_start, vdigits_end] */
1145n/a assert(vdigits_start < decpt && decpt <= vdigits_end);
1146n/a
1147n/a /* Compute an upper bound how much memory we need. This might be a few
1148n/a chars too long, but no big deal. */
1149n/a bufsize =
1150n/a /* sign, decimal point and trailing 0 byte */
1151n/a 3 +
1152n/a
1153n/a /* total digit count (including zero padding on both sides) */
1154n/a (vdigits_end - vdigits_start) +
1155n/a
1156n/a /* exponent "e+100", max 3 numerical digits */
1157n/a (use_exp ? 5 : 0);
1158n/a
1159n/a /* Now allocate the memory and initialize p to point to the start of
1160n/a it. */
1161n/a buf = (char *)PyMem_Malloc(bufsize);
1162n/a if (buf == NULL) {
1163n/a PyErr_NoMemory();
1164n/a goto exit;
1165n/a }
1166n/a p = buf;
1167n/a
1168n/a /* Add a negative sign if negative, and a plus sign if non-negative
1169n/a and always_add_sign is true. */
1170n/a if (sign == 1)
1171n/a *p++ = '-';
1172n/a else if (always_add_sign)
1173n/a *p++ = '+';
1174n/a
1175n/a /* note that exactly one of the three 'if' conditions is true,
1176n/a so we include exactly one decimal point */
1177n/a /* Zero padding on left of digit string */
1178n/a if (decpt <= 0) {
1179n/a memset(p, '0', decpt-vdigits_start);
1180n/a p += decpt - vdigits_start;
1181n/a *p++ = '.';
1182n/a memset(p, '0', 0-decpt);
1183n/a p += 0-decpt;
1184n/a }
1185n/a else {
1186n/a memset(p, '0', 0-vdigits_start);
1187n/a p += 0 - vdigits_start;
1188n/a }
1189n/a
1190n/a /* Digits, with included decimal point */
1191n/a if (0 < decpt && decpt <= digits_len) {
1192n/a strncpy(p, digits, decpt-0);
1193n/a p += decpt-0;
1194n/a *p++ = '.';
1195n/a strncpy(p, digits+decpt, digits_len-decpt);
1196n/a p += digits_len-decpt;
1197n/a }
1198n/a else {
1199n/a strncpy(p, digits, digits_len);
1200n/a p += digits_len;
1201n/a }
1202n/a
1203n/a /* And zeros on the right */
1204n/a if (digits_len < decpt) {
1205n/a memset(p, '0', decpt-digits_len);
1206n/a p += decpt-digits_len;
1207n/a *p++ = '.';
1208n/a memset(p, '0', vdigits_end-decpt);
1209n/a p += vdigits_end-decpt;
1210n/a }
1211n/a else {
1212n/a memset(p, '0', vdigits_end-digits_len);
1213n/a p += vdigits_end-digits_len;
1214n/a }
1215n/a
1216n/a /* Delete a trailing decimal pt unless using alternative formatting. */
1217n/a if (p[-1] == '.' && !use_alt_formatting)
1218n/a p--;
1219n/a
1220n/a /* Now that we've done zero padding, add an exponent if needed. */
1221n/a if (use_exp) {
1222n/a *p++ = float_strings[OFS_E][0];
1223n/a exp_len = sprintf(p, "%+.02d", exp);
1224n/a p += exp_len;
1225n/a }
1226n/a exit:
1227n/a if (buf) {
1228n/a *p = '\0';
1229n/a /* It's too late if this fails, as we've already stepped on
1230n/a memory that isn't ours. But it's an okay debugging test. */
1231n/a assert(p-buf < bufsize);
1232n/a }
1233n/a if (digits)
1234n/a _Py_dg_freedtoa(digits);
1235n/a
1236n/a return buf;
1237n/a}
1238n/a
1239n/a
1240n/aPyAPI_FUNC(char *) PyOS_double_to_string(double val,
1241n/a char format_code,
1242n/a int precision,
1243n/a int flags,
1244n/a int *type)
1245n/a{
1246n/a const char * const *float_strings = lc_float_strings;
1247n/a int mode;
1248n/a
1249n/a /* Validate format_code, and map upper and lower case. Compute the
1250n/a mode and make any adjustments as needed. */
1251n/a switch (format_code) {
1252n/a /* exponent */
1253n/a case 'E':
1254n/a float_strings = uc_float_strings;
1255n/a format_code = 'e';
1256n/a /* Fall through. */
1257n/a case 'e':
1258n/a mode = 2;
1259n/a precision++;
1260n/a break;
1261n/a
1262n/a /* fixed */
1263n/a case 'F':
1264n/a float_strings = uc_float_strings;
1265n/a format_code = 'f';
1266n/a /* Fall through. */
1267n/a case 'f':
1268n/a mode = 3;
1269n/a break;
1270n/a
1271n/a /* general */
1272n/a case 'G':
1273n/a float_strings = uc_float_strings;
1274n/a format_code = 'g';
1275n/a /* Fall through. */
1276n/a case 'g':
1277n/a mode = 2;
1278n/a /* precision 0 makes no sense for 'g' format; interpret as 1 */
1279n/a if (precision == 0)
1280n/a precision = 1;
1281n/a break;
1282n/a
1283n/a /* repr format */
1284n/a case 'r':
1285n/a mode = 0;
1286n/a /* Supplied precision is unused, must be 0. */
1287n/a if (precision != 0) {
1288n/a PyErr_BadInternalCall();
1289n/a return NULL;
1290n/a }
1291n/a break;
1292n/a
1293n/a default:
1294n/a PyErr_BadInternalCall();
1295n/a return NULL;
1296n/a }
1297n/a
1298n/a return format_float_short(val, format_code, mode, precision,
1299n/a flags & Py_DTSF_SIGN,
1300n/a flags & Py_DTSF_ADD_DOT_0,
1301n/a flags & Py_DTSF_ALT,
1302n/a float_strings, type);
1303n/a}
1304n/a#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */