Exemple #1
0
/*
 * _NumPyOS_ascii_strtod_plain:
 *
 * PyOS_ascii_strtod work-alike, with no enhanced features,
 * for forward compatibility with Python >= 2.7
 */
static double
NumPyOS_ascii_strtod_plain(const char *s, char** endptr)
{
    double result;
#if PY_VERSION_HEX >= 0x02070000
    NPY_ALLOW_C_API_DEF
    NPY_ALLOW_C_API
    result = PyOS_string_to_double(s, endptr, NULL);
    if (PyErr_Occurred()) {
        if (endptr) {
            *endptr = (char*)s;
        }
        PyErr_Clear();
    }
    NPY_DISABLE_C_API
#else
    result = PyOS_ascii_strtod(s, endptr);
#endif
    return result;
}
static PyObject *
strop_atof(PyObject *self, PyObject *args)
{
	char *s, *end;
	double x;
	char buffer[256]; /* For errors */

	WARN;
	if (!PyArg_ParseTuple(args, "s:atof", &s))
		return NULL;
	while (*s && isspace(Py_CHARMASK(*s)))
		s++;
	if (s[0] == '\0') {
		PyErr_SetString(PyExc_ValueError, "empty string for atof()");
		return NULL;
	}
	errno = 0;
	PyFPE_START_PROTECT("strop_atof", return 0)
	x = PyOS_ascii_strtod(s, &end);
	PyFPE_END_PROTECT(x)
	while (*end && isspace(Py_CHARMASK(*end)))
		end++;
	if (*end != '\0') {
		PyOS_snprintf(buffer, sizeof(buffer),
			      "invalid literal for atof(): %.200s", s);
		PyErr_SetString(PyExc_ValueError, buffer);
		return NULL;
	}
	else if (errno != 0) {
		PyOS_snprintf(buffer, sizeof(buffer), 
			      "atof() literal too large: %.200s", s);
		PyErr_SetString(PyExc_ValueError, buffer);
		return NULL;
	}
	return PyFloat_FromDouble(x);
}
Exemple #3
0
static PyObject *
complex_subtype_from_string(PyTypeObject *type, PyObject *v)
{
	const char *s, *start;
	char *end;
	double x=0.0, y=0.0, z;
	int got_re=0, got_im=0, got_bracket=0, done=0;
	int digit_or_dot;
	int sw_error=0;
	int sign;
	char buffer[256]; /* For errors */
#ifdef Py_USING_UNICODE
	char s_buffer[256];
#endif
	Py_ssize_t len;

	if (PyString_Check(v)) {
		s = PyString_AS_STRING(v);
		len = PyString_GET_SIZE(v);
	}
#ifdef Py_USING_UNICODE
	else if (PyUnicode_Check(v)) {
		if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
			PyErr_SetString(PyExc_ValueError,
				 "complex() literal too large to convert");
			return NULL;
		}
		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
					    PyUnicode_GET_SIZE(v),
					    s_buffer,
					    NULL))
			return NULL;
		s = s_buffer;
		len = strlen(s);
	}
#endif
	else if (PyObject_AsCharBuffer(v, &s, &len)) {
		PyErr_SetString(PyExc_TypeError,
				"complex() arg is not a string");
		return NULL;
	}

	/* position on first nonblank */
	start = s;
	while (*s && isspace(Py_CHARMASK(*s)))
		s++;
	if (s[0] == '\0') {
		PyErr_SetString(PyExc_ValueError,
				"complex() arg is an empty string");
		return NULL;
	}
	if (s[0] == '(') {
		/* Skip over possible bracket from repr(). */
		got_bracket = 1;
		s++;
		while (*s && isspace(Py_CHARMASK(*s)))
			s++;
	}

	z = -1.0;
	sign = 1;
	do {

		switch (*s) {

		case '\0':
			if (s-start != len) {
				PyErr_SetString(
					PyExc_ValueError,
					"complex() arg contains a null byte");
				return NULL;
			}
			if(!done) sw_error=1;
			break;

		case ')':
			if (!got_bracket || !(got_re || got_im)) {
				sw_error=1;
				break;
			}
			got_bracket=0;
			done=1;
			s++;
			while (*s && isspace(Py_CHARMASK(*s)))
				s++;
			if (*s) sw_error=1;
			break;

		case '-':
			sign = -1;
				/* Fallthrough */
		case '+':
			if (done)  sw_error=1;
			s++;
			if  (  *s=='\0'||*s=='+'||*s=='-'||*s==')'||
			       isspace(Py_CHARMASK(*s))  )  sw_error=1;
			break;

		case 'J':
		case 'j':
			if (got_im || done) {
				sw_error = 1;
				break;
			}
			if  (z<0.0) {
				y=sign;
			}
			else{
				y=sign*z;
			}
			got_im=1;
			s++;
			if  (*s!='+' && *s!='-' )
				done=1;
			break;

		default:
			if (isspace(Py_CHARMASK(*s))) {
				while (*s && isspace(Py_CHARMASK(*s)))
					s++;
				if (*s && *s != ')')
					sw_error=1;
				else
					done = 1;
				break;
			}
			digit_or_dot =
				(*s=='.' || isdigit(Py_CHARMASK(*s)));
			if  (done||!digit_or_dot) {
				sw_error=1;
				break;
			}
			errno = 0;
			PyFPE_START_PROTECT("strtod", return 0)
				z = PyOS_ascii_strtod(s, &end) ;
			PyFPE_END_PROTECT(z)
				if (errno != 0) {
					PyOS_snprintf(buffer, sizeof(buffer),
					  "float() out of range: %.150s", s);
					PyErr_SetString(
						PyExc_ValueError,
						buffer);
					return NULL;
				}
			s=end;
			if  (*s=='J' || *s=='j') {

				break;
			}
			if  (got_re) {
				sw_error=1;
				break;
			}

				/* accept a real part */
			x=sign*z;
			got_re=1;
			if  (got_im)  done=1;
			z = -1.0;
			sign = 1;
			break;

		}  /* end of switch  */

	} while (s - start < len && !sw_error);

	if (sw_error || got_bracket) {
		PyErr_SetString(PyExc_ValueError,
				"complex() arg is a malformed string");
		return NULL;
	}

	return complex_subtype_from_doubles(type, x, y);
}
Exemple #4
0
/* given a string convert to floating point and return it as a double.
 * this is to isolate possible unportabilities associated with declaring atof().
 * it's worth it because atof() is often some 50% faster than sscanf ("%lf");
 */
double
atod (char *buf)
{
     return (PyOS_ascii_strtod(buf, NULL));
}
Exemple #5
0
/*
 * NumPyOS_ascii_strtod:
 *
 * Work around bugs in PyOS_ascii_strtod
 */
static double
NumPyOS_ascii_strtod(const char *s, char** endptr)
{
    struct lconv *locale_data = localeconv();
    const char *decimal_point = locale_data->decimal_point;
    size_t decimal_point_len = strlen(decimal_point);

    char buffer[FLOAT_FORMATBUFLEN+1];
    const char *p;
    char *q;
    size_t n;
    double result;

    while (NumPyOS_ascii_isspace(*s)) {
        ++s;
    }

    /*
     * ##1
     *
     * Recognize POSIX inf/nan representations on all platforms.
     */
    p = s;
    result = 1.0;
    if (*p == '-') {
        result = -1.0;
        ++p;
    }
    else if (*p == '+') {
        ++p;
    }
    if (NumPyOS_ascii_strncasecmp(p, "nan", 3) == 0) {
        p += 3;
        if (*p == '(') {
            ++p;
            while (NumPyOS_ascii_isalnum(*p) || *p == '_') {
                ++p;
            }
            if (*p == ')') {
                ++p;
            }
        }
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        return NPY_NAN;
    }
    else if (NumPyOS_ascii_strncasecmp(p, "inf", 3) == 0) {
        p += 3;
        if (NumPyOS_ascii_strncasecmp(p, "inity", 5) == 0) {
            p += 5;
        }
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        return result*NPY_INFINITY;
    }
    /* End of ##1 */

    /*
     * ## 2
     *
     * At least Python versions <= 2.5.2 and <= 2.6.1
     *
     * Fails to do best-efforts parsing of strings of the form "1<DP>234"
     * where <DP> is the decimal point under the foreign locale.
     */
    if (decimal_point[0] != '.' || decimal_point[1] != 0) {
        p = s;
        if (*p == '+' || *p == '-') {
            ++p;
        }
        while (*p >= '0' && *p <= '9') {
            ++p;
        }
        if (strncmp(p, decimal_point, decimal_point_len) == 0) {
            n = (size_t)(p - s);
            if (n > FLOAT_FORMATBUFLEN) {
                n = FLOAT_FORMATBUFLEN;
            }
            memcpy(buffer, s, n);
            buffer[n] = '\0';
            result = PyOS_ascii_strtod(buffer, &q);
            if (endptr != NULL) {
                *endptr = (char*)(s + (q - buffer));
            }
            return result;
        }
    }
    /* End of ##2 */

    return PyOS_ascii_strtod(s, endptr);
}
Exemple #6
0
double
PyOS_ascii_atof(const char *nptr)
{
    return PyOS_ascii_strtod(nptr, NULL);
}