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')
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
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
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)
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)
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')