Example #1
0
def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
    """Convert a string s to a double, raising a Python
    exception on failure.  The set of accepted strings corresponds to
    the set of strings accepted by Python's float() constructor,
    except that s must not have leading or trailing whitespace.
    The conversion is independent of the current locale.

    If endptr is NULL, convert the whole string.  Raise
    ValueError and return -1.0 if the string is not a valid
    representation of a floating-point number.

    If endptr is not NULL, convert as much of the string as
    possible and set *endptr to point to the first unconverted
    character.  If no initial segment of the string is the valid
    representation of a floating-point number, set *endptr to point
    to the beginning of the string, raise ValueError, and return
    -1.0.

    If s represents a value that is too large to store in a float
    (for example, "1e500" is such a string on many platforms) then
    if overflow_exception is NULL return Py_HUGE_VAL (with
    an appropriate sign) and don't set any exception.  Otherwise,
    overflow_exception must point to a Python exception object;
    raise that exception and return -1.0.  In both cases, set
    *endptr to point to the first character after the converted value.

    If any other error occurs during the conversion (for example an
    out-of-memory error), set the appropriate Python exception and
    return -1.0.
    """
    user_endptr = True
    try:
        if not endptr:
            endptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
            user_endptr = False
        result = rdtoa.dg_strtod(s, endptr)
        endpos = (rffi.cast(rffi.LONG, endptr[0]) -
                  rffi.cast(rffi.LONG, s))
        if endpos == 0 or (not user_endptr and not endptr[0][0] == '\0'):
            raise OperationError(
                space.w_ValueError,
                space.wrap('invalid input at position %s' % endpos))
        err = rffi.cast(lltype.Signed, rposix._get_errno())
        if err == errno.ERANGE:
            rposix._set_errno(rffi.cast(rffi.INT, 0))
            if w_overflow_exception is None:
                if result > 0:
                    return rfloat.INFINITY
                else:
                    return -rfloat.INFINITY
            else:
                raise OperationError(w_overflow_exception,
                                     space.wrap('value too large'))
        return result
    finally:
        if not user_endptr:
            lltype.free(endptr, flavor='raw')
Example #2
0
def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
    """Convert a string s to a double, raising a Python
    exception on failure.  The set of accepted strings corresponds to
    the set of strings accepted by Python's float() constructor,
    except that s must not have leading or trailing whitespace.
    The conversion is independent of the current locale.

    If endptr is NULL, convert the whole string.  Raise
    ValueError and return -1.0 if the string is not a valid
    representation of a floating-point number.

    If endptr is not NULL, convert as much of the string as
    possible and set *endptr to point to the first unconverted
    character.  If no initial segment of the string is the valid
    representation of a floating-point number, set *endptr to point
    to the beginning of the string, raise ValueError, and return
    -1.0.

    If s represents a value that is too large to store in a float
    (for example, "1e500" is such a string on many platforms) then
    if overflow_exception is NULL return Py_HUGE_VAL (with
    an appropriate sign) and don't set any exception.  Otherwise,
    overflow_exception must point to a Python exception object;
    raise that exception and return -1.0.  In both cases, set
    *endptr to point to the first character after the converted value.

    If any other error occurs during the conversion (for example an
    out-of-memory error), set the appropriate Python exception and
    return -1.0.
    """
    user_endptr = True
    try:
        if not endptr:
            endptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
            user_endptr = False
        result = rdtoa.dg_strtod(s, endptr)
        endpos = (rffi.cast(rffi.LONG, endptr[0]) - rffi.cast(rffi.LONG, s))
        if endpos == 0 or (not user_endptr and not endptr[0][0] == '\0'):
            raise OperationError(
                space.w_ValueError,
                space.wrap('invalid input at position %s' % endpos))
        err = rffi.cast(lltype.Signed, rposix._get_errno())
        if err == errno.ERANGE:
            rposix._set_errno(rffi.cast(rffi.INT, 0))
            if w_overflow_exception is None:
                if result > 0:
                    return rfloat.INFINITY
                else:
                    return -rfloat.INFINITY
            else:
                raise OperationError(w_overflow_exception,
                                     space.wrap('value too large'))
        return result
    finally:
        if not user_endptr:
            lltype.free(endptr, flavor='raw')
Example #3
0
 def flush(self):
     if self.buf_count > 0:
         bytes = self.buf_count * rffi.sizeof(rffi.SIGNED)
         count = raw_os_write(self.fd,
                              rffi.cast(llmemory.Address, self.writebuffer),
                              rffi.cast(rffi.SIZE_T, bytes))
         if rffi.cast(lltype.Signed, count) != bytes:
             raise OSError(rffi.cast(lltype.Signed, rposix._get_errno()),
                           "raw_os_write failed")
         self.buf_count = 0
Example #4
0
 def flush(self):
     if self.buf_count > 0:
         bytes = self.buf_count * rffi.sizeof(rffi.LONG)
         count = raw_os_write(self.fd,
                              rffi.cast(llmemory.Address, self.writebuffer),
                              rffi.cast(rffi.SIZE_T, bytes))
         if rffi.cast(lltype.Signed, count) != bytes:
             raise OSError(rffi.cast(lltype.Signed, rposix._get_errno()),
                           "raw_os_write failed")
         self.buf_count = 0
Example #5
0
def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
    """Similar to PyErr_SetFromErrno(), with the additional behavior that if
    w_value is not NULL, it is passed to the constructor of type as a
    third parameter.  In the case of exceptions such as IOError and OSError,
    this is used to define the filename attribute of the exception instance.
    Return value: always NULL."""
    # XXX Doesn't actually do anything with PyErr_CheckSignals.
    errno = rffi.cast(lltype.Signed, rposix._get_errno())
    msg = os.strerror(errno)
    if w_value:
        w_error = space.call_function(w_type, space.wrap(errno),
                                      space.wrap(msg), w_value)
    else:
        w_error = space.call_function(w_type, space.wrap(errno),
                                      space.wrap(msg))
    raise OperationError(w_type, w_error)
Example #6
0
def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
    """Similar to PyErr_SetFromErrno(), with the additional behavior that if
    w_value is not NULL, it is passed to the constructor of type as a
    third parameter.  In the case of exceptions such as IOError and OSError,
    this is used to define the filename attribute of the exception instance.
    Return value: always NULL."""
    # XXX Doesn't actually do anything with PyErr_CheckSignals.
    errno = rffi.cast(lltype.Signed, rposix._get_errno())
    msg = _strerror(errno)
    if w_value:
        w_error = space.call_function(w_type,
                                      space.wrap(errno),
                                      space.wrap(msg),
                                      w_value)
    else:
        w_error = space.call_function(w_type,
                                      space.wrap(errno),
                                      space.wrap(msg))
    raise OperationError(w_type, w_error)
Example #7
0
def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
    """Convert a string s to a double, raising a Python
    exception on failure.  The set of accepted strings corresponds to
    the set of strings accepted by Python's float() constructor,
    except that s must not have leading or trailing whitespace.
    The conversion is independent of the current locale.

    If endptr is NULL, convert the whole string.  Raise
    ValueError and return -1.0 if the string is not a valid
    representation of a floating-point number.

    If endptr is not NULL, convert as much of the string as
    possible and set *endptr to point to the first unconverted
    character.  If no initial segment of the string is the valid
    representation of a floating-point number, set *endptr to point
    to the beginning of the string, raise ValueError, and return
    -1.0.

    If s represents a value that is too large to store in a float
    (for example, "1e500" is such a string on many platforms) then
    if overflow_exception is NULL return Py_HUGE_VAL (with
    an appropriate sign) and don't set any exception.  Otherwise,
    overflow_exception must point to a Python exception object;
    raise that exception and return -1.0.  In both cases, set
    *endptr to point to the first character after the converted value.

    If any other error occurs during the conversion (for example an
    out-of-memory error), set the appropriate Python exception and
    return -1.0.
    """
    user_endptr = True
    try:
        if not endptr:
            endptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
            user_endptr = False
        result = rdtoa.dg_strtod(s, endptr)
        endpos = (rffi.cast(rffi.LONG, endptr[0]) - rffi.cast(rffi.LONG, s))
        if endpos == 0 or (not user_endptr and not endptr[0][0] == '\0'):
            low = rffi.constcharp2str(s).lower()
            sz = 0
            if len(low) < 3:
                pass
            elif low[0] == '-':
                if low.startswith('-infinity'):
                    result = -rfloat.INFINITY
                    sz = len("-infinity")
                elif low.startswith("-inf"):
                    result = -rfloat.INFINITY
                    sz = 4
                elif low.startswith("-nan"):
                    result = -rfloat.NAN
                    sz = 4
            elif low[0] == '+':
                if low.startswith("+infinity"):
                    result = rfloat.INFINITY
                    sz = len("+infinity")
                elif low.startswith("+inf"):
                    result = rfloat.INFINITY
                    sz = 4
                elif low.startswith("+nan"):
                    result = rfloat.NAN
                    sz = 4
            elif low.startswith("infinity"):
                result = rfloat.INFINITY
                sz = len("infinity")
            elif low.startswith("inf"):
                result = rfloat.INFINITY
                sz = 3
            elif low.startswith("nan"):
                result = rfloat.NAN
                sz = 3
            # result is set to 0.0 for a parse_error in dtoa.c
            # if it changed, we must have sucessfully converted
            if result != 0.0:
                if endptr:
                    endptr[0] = rffi.cast(rffi.CCHARP, rffi.ptradd(s, sz))
                return result
            raise oefmt(space.w_ValueError, "invalid input at position %d",
                        endpos)
        err = rffi.cast(lltype.Signed, rposix._get_errno())
        if err == errno.ERANGE:
            rposix._set_errno(rffi.cast(rffi.INT, 0))
            if w_overflow_exception is None:
                if result > 0:
                    return rfloat.INFINITY
                else:
                    return -rfloat.INFINITY
            else:
                raise oefmt(w_overflow_exception, "value too large")
        return result
    finally:
        if not user_endptr:
            lltype.free(endptr, flavor='raw')