--=-UjU31ROv+4O9JKpq7ZBY Content-Type: text/plain Content-Transfer-Encoding: 7bit Here's the patch. Also 2 new source files: - pystrtod.h goes to Include/ - pystrtod.c goes to Python/ The next step is to ask glib authors for permission to relicense the code. Also, the locale module should be changed, to allow LC_NUMERIC to be changed, etc. Regards. -- Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gustavo@users.sourceforge.net> --=-UjU31ROv+4O9JKpq7ZBY Content-Disposition: attachment; filename=numeric.diff Content-Type: text/x-patch; name=numeric.diff; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Only in Python-2.3b2-gjc/Include: pystrtod.h diff -rup Python-2.3b2/Include/Python.h Python-2.3b2-gjc/Include/Python.h --- Python-2.3b2/Include/Python.h 2002-08-12 08:21:56.000000000 +0100 +++ Python-2.3b2-gjc/Include/Python.h 2003-07-17 00:03:47.000000000 +0100 @@ -113,6 +113,8 @@ #include "abstract.h" +#include "pystrtod.h" + /* _Py_Mangle is defined in compile.c */ PyAPI_FUNC(int) _Py_Mangle(char *p, char *name, \ char *buffer, size_t maxlen); diff -rup Python-2.3b2/Makefile.pre.in Python-2.3b2-gjc/Makefile.pre.in --- Python-2.3b2/Makefile.pre.in 2003-06-21 14:26:28.000000000 +0100 +++ Python-2.3b2-gjc/Makefile.pre.in 2003-07-16 23:54:30.000000000 +0100 @@ -244,6 +244,7 @@ PYTHON_OBJS= \ Python/sysmodule.o \ Python/traceback.o \ Python/getopt.o \ + Python/pystrtod.o \ Python/$(DYNLOADFILE) \ $(MACHDEP_OBJS) \ $(THREADOBJ) diff -rup Python-2.3b2/Modules/cPickle.c Python-2.3b2-gjc/Modules/cPickle.c --- Python-2.3b2/Modules/cPickle.c 2003-06-16 21:19:49.000000000 +0100 +++ Python-2.3b2-gjc/Modules/cPickle.c 2003-07-19 12:08:17.000000000 +0100 @@ -3314,7 +3314,7 @@ load_float(Unpicklerobject *self) if (!( s=pystrndup(s,len))) return -1; errno = 0; - d = strtod(s, &endptr); + d = PyOS_strtod(s, &endptr); if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) { PyErr_SetString(PyExc_ValueError, diff -rup Python-2.3b2/Modules/stropmodule.c Python-2.3b2-gjc/Modules/stropmodule.c --- Python-2.3b2/Modules/stropmodule.c 2002-08-02 03:27:13.000000000 +0100 +++ Python-2.3b2-gjc/Modules/stropmodule.c 2003-07-19 12:08:17.000000000 +0100 @@ -838,7 +838,6 @@ PyDoc_STRVAR(atof__doc__, static PyObject * strop_atof(PyObject *self, PyObject *args) { - extern double strtod(const char *, char **); char *s, *end; double x; char buffer[256]; /* For errors */ @@ -854,7 +853,7 @@ strop_atof(PyObject *self, PyObject *arg } errno = 0; PyFPE_START_PROTECT("strop_atof", return 0) - x = strtod(s, &end); + x = PyOS_strtod(s, &end); PyFPE_END_PROTECT(x) while (*end && isspace(Py_CHARMASK(*end))) end++; diff -rup Python-2.3b2/Objects/complexobject.c Python-2.3b2-gjc/Objects/complexobject.c --- Python-2.3b2/Objects/complexobject.c 2003-06-17 21:22:24.000000000 +0100 +++ Python-2.3b2-gjc/Objects/complexobject.c 2003-07-19 12:56:59.000000000 +0100 @@ -272,13 +272,19 @@ complex_dealloc(PyObject *op) static void complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) { - if (v->cval.real == 0.) - PyOS_snprintf(buf, bufsz, "%.*gj", - precision, v->cval.imag); - else - PyOS_snprintf(buf, bufsz, "(%.*g%+.*gj)", - precision, v->cval.real, - precision, v->cval.imag); + char format[32]; + if (v->cval.real == 0.) { + PyOS_snprintf(format, 32, "%%.%ig", precision); + PyOS_formatd(buf, bufsz, format, v->cval.imag); + strncat(buf, "j", bufsz); + } else { + char re[64], im[64]; + + PyOS_snprintf(format, 32, "%%.%ig", precision); + PyOS_formatd(re, 64, format, v->cval.real); + PyOS_formatd(im, 64, format, v->cval.imag); + PyOS_snprintf(buf, bufsz, "(%s+%sj)", re, im); + } } static int @@ -662,7 +668,6 @@ static PyMemberDef complex_members[] = { static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { - extern double strtod(const char *, char **); const char *s, *start; char *end; double x=0.0, y=0.0, z; @@ -774,7 +779,7 @@ complex_subtype_from_string(PyTypeObject } errno = 0; PyFPE_START_PROTECT("strtod", return 0) - z = strtod(s, &end) ; + z = PyOS_strtod(s, &end) ; PyFPE_END_PROTECT(z) if (errno != 0) { PyOS_snprintf(buffer, sizeof(buffer), diff -rup Python-2.3b2/Objects/floatobject.c Python-2.3b2-gjc/Objects/floatobject.c --- Python-2.3b2/Objects/floatobject.c 2003-06-28 21:04:24.000000000 +0100 +++ Python-2.3b2-gjc/Objects/floatobject.c 2003-07-19 12:54:30.000000000 +0100 @@ -142,7 +142,7 @@ PyFloat_FromString(PyObject *v, char **p * key off errno. */ PyFPE_START_PROTECT("strtod", return NULL) - x = strtod(s, (char **)&end); + x = PyOS_strtod(s, (char **)&end); PyFPE_END_PROTECT(x) errno = 0; /* Believe it or not, Solaris 2.6 can move end *beyond* the null @@ -174,7 +174,7 @@ PyFloat_FromString(PyObject *v, char **p /* See above -- may have been strtod being anal about denorms. */ PyFPE_START_PROTECT("atof", return NULL) - x = atof(s); + x = PyOS_atof(s); PyFPE_END_PROTECT(x) errno = 0; /* whether atof ever set errno is undefined */ } @@ -233,6 +233,7 @@ static void format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) { register char *cp; + char format[32]; /* Subroutine for float_repr and float_print. We want float numbers to be recognizable as such, i.e., they should contain a decimal point or an exponent. @@ -240,7 +241,8 @@ format_float(char *buf, size_t buflen, P in such cases, we append ".0" to the string. */ assert(PyFloat_Check(v)); - PyOS_snprintf(buf, buflen, "%.*g", precision, v->ob_fval); + PyOS_snprintf(format, 32, "%%.%ig", precision); + PyOS_formatd(buf, buflen, format, v->ob_fval); cp = buf; if (*cp == '-') cp++; diff -rup Python-2.3b2/Python/compile.c Python-2.3b2-gjc/Python/compile.c --- Python-2.3b2/Python/compile.c 2003-06-20 17:13:17.000000000 +0100 +++ Python-2.3b2-gjc/Python/compile.c 2003-07-19 12:06:56.000000000 +0100 @@ -1286,7 +1286,7 @@ parsenumber(struct compiling *c, char *s Py_complex z; z.real = 0.; PyFPE_START_PROTECT("atof", return 0) - z.imag = atof(s); + z.imag = PyOS_atof(s); PyFPE_END_PROTECT(z) return PyComplex_FromCComplex(z); } @@ -1294,7 +1294,7 @@ parsenumber(struct compiling *c, char *s #endif { PyFPE_START_PROTECT("atof", return 0) - dx = atof(s); + dx = PyOS_atof(s); PyFPE_END_PROTECT(dx) return PyFloat_FromDouble(dx); } diff -rup Python-2.3b2/Python/marshal.c Python-2.3b2-gjc/Python/marshal.c --- Python-2.3b2/Python/marshal.c 2002-07-30 12:44:44.000000000 +0100 +++ Python-2.3b2-gjc/Python/marshal.c 2003-07-19 12:11:08.000000000 +0100 @@ -447,7 +447,7 @@ r_object(RFILE *p) } buf[n] = '\0'; PyFPE_START_PROTECT("atof", return 0) - dx = atof(buf); + dx = PyOS_atof(buf); PyFPE_END_PROTECT(dx) return PyFloat_FromDouble(dx); } @@ -465,7 +465,7 @@ r_object(RFILE *p) } buf[n] = '\0'; PyFPE_START_PROTECT("atof", return 0) - c.real = atof(buf); + c.real = PyOS_atof(buf); PyFPE_END_PROTECT(c) n = r_byte(p); if (r_string(buf, (int)n, p) != n) { @@ -475,7 +475,7 @@ r_object(RFILE *p) } buf[n] = '\0'; PyFPE_START_PROTECT("atof", return 0) - c.imag = atof(buf); + c.imag = PyOS_atof(buf); PyFPE_END_PROTECT(c) return PyComplex_FromCComplex(c); } Only in Python-2.3b2-gjc/Python: pystrtod.c --=-UjU31ROv+4O9JKpq7ZBY Content-Disposition: attachment; filename=pystrtod.c Content-Type: text/x-c; name=pystrtod.c; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit /* -*- Mode: C; c-file-style: "python" -*- */ #include "Python.h" #include <stdlib.h> #include <locale.h> #include <assert.h> #include <string.h> #include <errno.h> #include <ctype.h> //#define __PYSTRTOD_DEBUG /* Note: glib functions are based on gstrfuncs.c, version 1.94.2.3 */ /* ------------------------------------------ */ /* <glib-stuff> */ /* glib uses gnu-style indenting/spacing */ /* for compatibility */ #ifdef NDEBUG # define g_return_val_if_fail(condition, value) # define g_return_if_fail(condition) #else # define g_return_val_if_fail(condition, value) \ if (!(condition)) { \ /*give warning here*/; \ return (value); \ } # define g_return_if_fail(condition, value) \ if (!(condition)) { \ /*give warning here*/; \ return; \ } #endif #define g_assert(foo) assert(foo) #define g_malloc(foo) malloc(foo) #define g_free(foo) free(foo) #define _g_snprintf PyOS_snprintf /* ... */ typedef char gchar; typedef short gshort; typedef long glong; typedef int gint; typedef gint gboolean; typedef unsigned char guchar; typedef unsigned short gushort; typedef unsigned long gulong; typedef unsigned int guint; typedef float gfloat; typedef double gdouble; typedef signed char gint8; typedef unsigned char guint8; typedef signed short gint16; typedef unsigned short guint16; typedef signed int gint32; typedef unsigned int guint32; static const guint16 ascii_table_data[256] = { 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004 /* the upper 128 are all zeroes */ }; const guint16 * const g_ascii_table = ascii_table_data; /* Functions like the ones in <ctype.h> that are not affected by locale. */ typedef enum { G_ASCII_ALNUM = 1 << 0, G_ASCII_ALPHA = 1 << 1, G_ASCII_CNTRL = 1 << 2, G_ASCII_DIGIT = 1 << 3, G_ASCII_GRAPH = 1 << 4, G_ASCII_LOWER = 1 << 5, G_ASCII_PRINT = 1 << 6, G_ASCII_PUNCT = 1 << 7, G_ASCII_SPACE = 1 << 8, G_ASCII_UPPER = 1 << 9, G_ASCII_XDIGIT = 1 << 10 } GAsciiType; #define g_ascii_isalnum(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0) #define g_ascii_isalpha(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_ALPHA) != 0) #define g_ascii_iscntrl(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_CNTRL) != 0) #define g_ascii_isdigit(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0) #define g_ascii_isgraph(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_GRAPH) != 0) #define g_ascii_islower(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_LOWER) != 0) #define g_ascii_isprint(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0) #define g_ascii_ispunct(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_PUNCT) != 0) #define g_ascii_isspace(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_SPACE) != 0) #define g_ascii_isupper(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_UPPER) != 0) #define g_ascii_isxdigit(c) \ ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0) /** * g_ascii_strtod: * @nptr: the string to convert to a numeric value. * @endptr: if non-%NULL, it returns the character after * the last character used in the conversion. * * Converts a string to a #gdouble value. * This function behaves like the standard strtod() function * does in the C locale. It does this without actually * changing the current locale, since that would not be * thread-safe. * * This function is typically used when reading configuration * files or other non-user input that should be locale independent. * To handle input from the user you should normally use the * locale-sensitive system strtod() function. * * To convert from a #gdouble to a string in a locale-insensitive * way, use g_ascii_dtostr(). * * If the correct value would cause overflow, plus or minus %HUGE_VAL * is returned (according to the sign of the value), and %ERANGE is * stored in %errno. If the correct value would cause underflow, * zero is returned and %ERANGE is stored in %errno. * * This function resets %errno before calling strtod() so that * you can reliably detect overflow and underflow. * * Return value: the #gdouble value. **/ static gdouble g_ascii_strtod (const gchar *nptr, gchar **endptr) { gchar *fail_pos; gdouble val; struct lconv *locale_data; const char *decimal_point; int decimal_point_len; const char *p, *decimal_point_pos; const char *end = NULL; /* Silence gcc */ g_return_val_if_fail (nptr != NULL, 0); fail_pos = NULL; locale_data = localeconv (); decimal_point = locale_data->decimal_point; decimal_point_len = strlen (decimal_point); g_assert (decimal_point_len != 0); decimal_point_pos = NULL; if (decimal_point[0] != '.' || decimal_point[1] != 0) { p = nptr; /* Skip leading space */ while (g_ascii_isspace (*p)) p++; /* Skip leading optional sign */ if (*p == '+' || *p == '-') p++; if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { p += 2; /* HEX - find the (optional) decimal point */ while (g_ascii_isxdigit (*p)) p++; if (*p == '.') { decimal_point_pos = p++; while (g_ascii_isxdigit (*p)) p++; if (*p == 'p' || *p == 'P') p++; if (*p == '+' || *p == '-') p++; while (g_ascii_isdigit (*p)) p++; end = p; } } else { while (g_ascii_isdigit (*p)) p++; if (*p == '.') { decimal_point_pos = p++; while (g_ascii_isdigit (*p)) p++; if (*p == 'e' || *p == 'E') p++; if (*p == '+' || *p == '-') p++; while (g_ascii_isdigit (*p)) p++; end = p; } } /* For the other cases, we need not convert the decimal point */ } /* Set errno to zero, so that we can distinguish zero results and underflows */ errno = 0; if (decimal_point_pos) { char *copy, *c; /* We need to convert the '.' to the locale specific decimal point */ copy = g_malloc (end - nptr + 1 + decimal_point_len); c = copy; memcpy (c, nptr, decimal_point_pos - nptr); c += decimal_point_pos - nptr; memcpy (c, decimal_point, decimal_point_len); c += decimal_point_len; memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); c += end - (decimal_point_pos + 1); *c = 0; val = strtod (copy, &fail_pos); if (fail_pos) { if (fail_pos > decimal_point_pos) fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); else fail_pos = (char *)nptr + (fail_pos - copy); } g_free (copy); } else val = strtod (nptr, &fail_pos); if (endptr) *endptr = fail_pos; return val; } /** * g_ascii_formatd: * @buffer: A buffer to place the resulting string in * @buf_len: The length of the buffer. * @format: The printf()-style format to use for the * code to use for converting. * @d: The #gdouble to convert * * Converts a #gdouble to a string, using the '.' as * decimal point. To format the number you pass in * a printf()-style format string. Allowed conversion * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. * * If you just want to want to serialize the value into a * string, use g_ascii_dtostr(). * * Return value: The pointer to the buffer with the converted string. **/ static gchar * g_ascii_formatd (gchar *buffer, gint buf_len, const gchar *format, gdouble d) { struct lconv *locale_data; const char *decimal_point; int decimal_point_len; gchar *p; int rest_len; gchar format_char; g_return_val_if_fail (buffer != NULL, NULL); g_return_val_if_fail (format[0] == '%', NULL); g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); format_char = format[strlen (format) - 1]; g_return_val_if_fail (format_char == 'e' || format_char == 'E' || format_char == 'f' || format_char == 'F' || format_char == 'g' || format_char == 'G', NULL); if (format[0] != '%') return NULL; if (strpbrk (format + 1, "'l%")) return NULL; if (!(format_char == 'e' || format_char == 'E' || format_char == 'f' || format_char == 'F' || format_char == 'g' || format_char == 'G')) return NULL; _g_snprintf (buffer, buf_len, format, d); locale_data = localeconv (); decimal_point = locale_data->decimal_point; decimal_point_len = strlen (decimal_point); g_assert (decimal_point_len != 0); if (decimal_point[0] != '.' || decimal_point[1] != 0) { p = buffer; if (*p == '+' || *p == '-') p++; while (isdigit ((guchar)*p)) p++; if (strncmp (p, decimal_point, decimal_point_len) == 0) { *p = '.'; p++; if (decimal_point_len > 1) { rest_len = strlen (p + (decimal_point_len-1)); memmove (p, p + (decimal_point_len-1), rest_len); p[rest_len] = 0; } } } return buffer; } /* </glib-stuff> */ /* ------------------------------------------ */ #ifdef __PYSTRTOD_DEBUG # include <stdio.h> #endif double PyOS_strtod(const char *str, char **ptr) { #ifdef __PYSTRTOD_DEBUG fprintf(stderr, ">>>!!! calling g_ascii_strtod('%s')\n", str); #endif return g_ascii_strtod(str, ptr); } double PyOS_atof(const char *str) { #ifdef __PYSTRTOD_DEBUG fprintf(stderr, ">>>!!! calling g_ascii_strtod('%s')\n", str); #endif return g_ascii_strtod(str, NULL); } void PyOS_formatd(char *buffer, int buf_len, const char *format, double d) { #ifdef __PYSTRTOD_DEBUG fprintf(stderr, ">>>!!! calling g_ascii_formatd('%s', %f)\n", format, d); #endif g_ascii_formatd(buffer, buf_len, format, d); #ifdef __PYSTRTOD_DEBUG fprintf(stderr, ">>>!!! g_ascii_formatd: \"%s\"\n", buffer); #endif } --=-UjU31ROv+4O9JKpq7ZBY Content-Disposition: attachment; filename=pystrtod.h Content-Type: text/x-c-header; name=pystrtod.h; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit #ifndef Py_STRTOD_H #define Py_STRTOD_H #ifdef __cplusplus extern "C" { #endif double PyOS_strtod(const char *str, char **ptr); double PyOS_atof(const char *str); void PyOS_formatd(char *buffer, int buf_len, const char *format, double d); #ifdef __cplusplus } #endif #endif /* !Py_STRTOD_H */ --=-UjU31ROv+4O9JKpq7ZBY--
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4