FreeBSD/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
/*
 * Convert a string of the form '100G' into a real number.  Used when setting
 * properties or creating a volume.  'buf' is used to place an extended error
 * message for the caller to use.
 */
Convert a string of the form '100G' into a real number.  Used when setting
properties or creating a volume.  'buf' is used to place an extended error
message for the caller to use.
Convert a string of the form ' 100G ' into a real number . Used when setting properties or creating a volume . ' buf ' is used to place an extended error message for the caller to use .
int
zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
{
	char *end;
	int shift;
	*num = 0;
	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
		if (hdl)
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "bad numeric value '%s'"), value);
		return (-1);
	}
	errno = 0;
	*num = strtoull(value, &end, 10);
	if (errno == ERANGE) {
		if (hdl)
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "numeric value is too large"));
		return (-1);
	}
	if (*end == '.') {
		double fval = strtod(value, &end);
		if ((shift = str2shift(hdl, end)) == -1)
			return (-1);
		fval *= pow(2, shift);
		if (fval > UINT64_MAX) {
			if (hdl)
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "numeric value is too large"));
			return (-1);
		}
		*num = (uint64_t)fval;
	} else {
		if ((shift = str2shift(hdl, end)) == -1)
			return (-1);
		if (shift >= 64 || (*num << shift) >> shift != *num) {
			if (hdl)
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "numeric value is too large"));
			return (-1);
		}
		*num <<= shift;
	}
	return (0);
}
int zfs_nicestrtonum ( libzfs_handle_t * hdl , const char * value , uint64_t * num ) { char * end ; int shift ; * num = 0 ; if ( ( value [ 0 ] < ' ' || value [ 0 ] > ' ' ) && value [ 0 ] != ' ' ) { if ( hdl ) zfs_error_aux ( hdl , dgettext ( TEXT_DOMAIN , " " ) , value ) ; return ( -1 ) ; } errno = 0 ; * num = strtoull ( value , & end , 10 ) ; if ( errno == ERANGE ) { if ( hdl ) zfs_error_aux ( hdl , dgettext ( TEXT_DOMAIN , " " ) ) ; return ( -1 ) ; } if ( * end == ' ' ) { double fval = strtod ( value , & end ) ; if ( ( shift = str2shift ( hdl , end ) ) == -1 ) return ( -1 ) ; fval *= pow ( 2 , shift ) ; if ( fval > UINT64_MAX ) { if ( hdl ) zfs_error_aux ( hdl , dgettext ( TEXT_DOMAIN , " " ) ) ; return ( -1 ) ; } * num = ( uint64_t ) fval ; } else { if ( ( shift = str2shift ( hdl , end ) ) == -1 ) return ( -1 ) ; if ( shift >= 64 || ( * num << shift ) >> shift != * num ) { if ( hdl ) zfs_error_aux ( hdl , dgettext ( TEXT_DOMAIN , " " ) ) ; return ( -1 ) ; } * num <<= shift ; } return ( 0 ) ; }
Convert a string of the form '100G' into a real number.
Convert a string of the form ' 100G ' into a real number .
/* Check to see if this looks like a number.  */ /* Rely on strtoull() to process the numeric portion.  */ /*
	 * Check for ERANGE, which indicates that the value is too large to fit
	 * in a 64-bit value.
	 */ /*
	 * If we have a decimal value, then do the computation with floating
	 * point arithmetic.  Otherwise, use standard arithmetic.
	 */ /* Check for overflow */