2016-09-07 09:14:30 +03:00
/*******************************************************************************
*
* Module Name : utstrtoul64 - string to 64 - bit integer support
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2017-02-08 06:00:08 +03:00
* Copyright ( C ) 2000 - 2017 , Intel Corp .
2016-09-07 09:14:30 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions , and the following disclaimer ,
* without modification .
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the " NO WARRANTY " disclaimer below
* ( " Disclaimer " ) and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution .
* 3. Neither the names of the above - listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* Alternatively , this software may be distributed under the terms of the
* GNU General Public License ( " GPL " ) version 2 as published by the Free
* Software Foundation .
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT ,
* STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES .
*/
# include <acpi/acpi.h>
# include "accommon.h"
/*******************************************************************************
*
* The functions in this module satisfy the need for 64 - bit string - to - integer
* conversions on both 32 - bit and 64 - bit platforms .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ( " utstrtoul64 " )
/* Local prototypes */
static u64 acpi_ut_strtoul_base10 ( char * string , u32 flags ) ;
static u64 acpi_ut_strtoul_base16 ( char * string , u32 flags ) ;
/*******************************************************************************
*
* String conversion rules as written in the ACPI specification . The error
* conditions and behavior are different depending on the type of conversion .
*
*
* Implicit data type conversion : string - to - integer
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Base is always 16. This is the ACPI_STRTOUL_BASE16 case .
*
* Example :
* Add ( " BA98 " , Arg0 , Local0 )
*
* The integer is initialized to the value zero .
* The ASCII string is interpreted as a hexadecimal constant .
*
* 1 ) A " 0x " prefix is not allowed . However , ACPICA allows this for
* compatibility with previous ACPICA . ( NO ERROR )
*
* 2 ) Terminates when the size of an integer is reached ( 32 or 64 bits ) .
* ( NO ERROR )
*
* 3 ) The first non - hex character terminates the conversion without error .
* ( NO ERROR )
*
* 4 ) Conversion of a null ( zero - length ) string to an integer is not
* allowed . However , ACPICA allows this for compatibility with previous
* ACPICA . This conversion returns the value 0. ( NO ERROR )
*
*
* Explicit data type conversion : to_integer ( ) with string operand
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Base is either 10 ( default ) or 16 ( with 0 x prefix )
*
* Examples :
* to_integer ( " 1000 " )
* to_integer ( " 0xABCD " )
*
* 1 ) Can be ( must be ) either a decimal or hexadecimal numeric string .
* A hex value must be prefixed by " 0x " or it is interpreted as a decimal .
*
* 2 ) The value must not exceed the maximum of an integer value . ACPI spec
* states the behavior is " unpredictable " , so ACPICA matches the behavior
* of the implicit conversion case . ( NO ERROR )
*
* 3 ) Behavior on the first non - hex character is not specified by the ACPI
* spec , so ACPICA matches the behavior of the implicit conversion case
* and terminates . ( NO ERROR )
*
* 4 ) A null ( zero - length ) string is illegal .
* However , ACPICA allows this for compatibility with previous ACPICA .
* This conversion returns the value 0. ( NO ERROR )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*******************************************************************************
*
* FUNCTION : acpi_ut_strtoul64
*
* PARAMETERS : string - Null terminated input string
* flags - Conversion info , see below
* return_value - Where the converted integer is
* returned
*
* RETURN : Status and Converted value
*
* DESCRIPTION : Convert a string into an unsigned value . Performs either a
* 32 - bit or 64 - bit conversion , depending on the input integer
* size in Flags ( often the current mode of the interpreter ) .
*
* Values for Flags :
* ACPI_STRTOUL_32BIT - Max integer value is 32 bits
* ACPI_STRTOUL_64BIT - Max integer value is 64 bits
* ACPI_STRTOUL_BASE16 - Input string is hexadecimal . Default
* is 10 / 16 based on string prefix ( 0 x ) .
*
* NOTES :
* Negative numbers are not supported , as they are not supported by ACPI .
*
* Supports only base 16 or base 10 strings / values . Does not
* support Octal strings , as these are not supported by ACPI .
*
* Current users of this support :
*
* interpreter - Implicit and explicit conversions , GPE method names
* debugger - Command line input string conversion
* iASL - Main parser , conversion of constants to integers
* iASL - Data Table Compiler parser ( constant math expressions )
* iASL - Preprocessor ( constant math expressions )
* acpi_dump - Input table addresses
* acpi_exec - Testing of the acpi_ut_strtoul64 function
*
* Note concerning callers :
* acpi_gbl_integer_byte_width can be used to set the 32 / 64 limit . If used ,
* this global should be set to the proper width . For the core ACPICA code ,
* this width depends on the DSDT version . For iASL , the default byte
* width is always 8 for the parser , but error checking is performed later
* to flag cases where a 64 - bit constant is defined in a 32 - bit DSDT / SSDT .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status acpi_ut_strtoul64 ( char * string , u32 flags , u64 * return_value )
{
acpi_status status = AE_OK ;
u32 base ;
ACPI_FUNCTION_TRACE_STR ( ut_strtoul64 , string ) ;
/* Parameter validation */
if ( ! string | | ! return_value ) {
return_ACPI_STATUS ( AE_BAD_PARAMETER ) ;
}
* return_value = 0 ;
/* Check for zero-length string, returns 0 */
if ( * string = = 0 ) {
return_ACPI_STATUS ( AE_OK ) ;
}
/* Skip over any white space at start of string */
while ( isspace ( ( int ) * string ) ) {
string + + ;
}
/* End of string? return 0 */
if ( * string = = 0 ) {
return_ACPI_STATUS ( AE_OK ) ;
}
/*
* 1 ) The " 0x " prefix indicates base 16. Per the ACPI specification ,
* the " 0x " prefix is only allowed for implicit ( non - strict ) conversions .
* However , we always allow it for compatibility with older ACPICA .
*/
if ( ( * string = = ACPI_ASCII_ZERO ) & &
( tolower ( ( int ) * ( string + 1 ) ) = = ' x ' ) ) {
string + = 2 ; /* Go past the 0x */
if ( * string = = 0 ) {
return_ACPI_STATUS ( AE_OK ) ; /* Return value 0 */
}
base = 16 ;
}
/* 2) Force to base 16 (implicit conversion case) */
else if ( flags & ACPI_STRTOUL_BASE16 ) {
base = 16 ;
}
/* 3) Default fallback is to Base 10 */
else {
base = 10 ;
}
/* Skip all leading zeros */
while ( * string = = ACPI_ASCII_ZERO ) {
string + + ;
if ( * string = = 0 ) {
return_ACPI_STATUS ( AE_OK ) ; /* Return value 0 */
}
}
/* Perform the base 16 or 10 conversion */
if ( base = = 16 ) {
* return_value = acpi_ut_strtoul_base16 ( string , flags ) ;
} else {
* return_value = acpi_ut_strtoul_base10 ( string , flags ) ;
}
return_ACPI_STATUS ( status ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_ut_strtoul_base10
*
* PARAMETERS : string - Null terminated input string
* flags - Conversion info
*
* RETURN : 64 - bit converted integer
*
* DESCRIPTION : Performs a base 10 conversion of the input string to an
* integer value , either 32 or 64 bits .
* Note : String must be valid and non - null .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static u64 acpi_ut_strtoul_base10 ( char * string , u32 flags )
{
int ascii_digit ;
u64 next_value ;
u64 return_value = 0 ;
/* Main loop: convert each ASCII byte in the input string */
while ( * string ) {
ascii_digit = * string ;
if ( ! isdigit ( ascii_digit ) ) {
/* Not ASCII 0-9, terminate */
goto exit ;
}
/* Convert and insert (add) the decimal digit */
next_value =
( return_value * 10 ) + ( ascii_digit - ACPI_ASCII_ZERO ) ;
/* Check for overflow (32 or 64 bit) - return current converted value */
if ( ( ( flags & ACPI_STRTOUL_32BIT ) & & ( next_value > ACPI_UINT32_MAX ) ) | | ( next_value < return_value ) ) { /* 64-bit overflow case */
goto exit ;
}
return_value = next_value ;
string + + ;
}
exit :
return ( return_value ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_ut_strtoul_base16
*
* PARAMETERS : string - Null terminated input string
* flags - conversion info
*
* RETURN : 64 - bit converted integer
*
* DESCRIPTION : Performs a base 16 conversion of the input string to an
* integer value , either 32 or 64 bits .
* Note : String must be valid and non - null .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static u64 acpi_ut_strtoul_base16 ( char * string , u32 flags )
{
int ascii_digit ;
u32 valid_digits = 1 ;
u64 return_value = 0 ;
/* Main loop: convert each ASCII byte in the input string */
while ( * string ) {
/* Check for overflow (32 or 64 bit) - return current converted value */
if ( ( valid_digits > 16 ) | |
( ( valid_digits > 8 ) & & ( flags & ACPI_STRTOUL_32BIT ) ) ) {
goto exit ;
}
ascii_digit = * string ;
if ( ! isxdigit ( ascii_digit ) ) {
/* Not Hex ASCII A-F, a-f, or 0-9, terminate */
goto exit ;
}
/* Convert and insert the hex digit */
return_value =
( return_value < < 4 ) |
acpi_ut_ascii_char_to_hex ( ascii_digit ) ;
string + + ;
valid_digits + + ;
}
exit :
return ( return_value ) ;
}