2018-03-15 02:13:07 +03:00
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2016-09-07 09:14:30 +03:00
/*******************************************************************************
*
2017-09-20 05:00:43 +03:00
* Module Name : utstrtoul64 - String - to - integer conversion support for both
* 64 - bit and 32 - bit integers
2016-09-07 09:14:30 +03:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <acpi/acpi.h>
# include "accommon.h"
# define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ( " utstrtoul64 " )
/*******************************************************************************
*
2017-09-20 05:00:43 +03:00
* This module contains the top - level string to 64 / 32 - bit unsigned integer
2017-09-20 05:00:36 +03:00
* conversion functions :
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:43 +03:00
* 1 ) A standard strtoul ( ) function that supports 64 - bit integers , base
* 8 / 10 / 16 , with integer overflow support . This is used mainly by the
* iASL compiler , which implements tighter constraints on integer
* constants than the runtime ( interpreter ) integer - to - string conversions .
2017-09-20 05:00:36 +03:00
* 2 ) Runtime " Explicit conversion " as defined in the ACPI specification .
* 3 ) Runtime " Implicit conversion " as defined in the ACPI specification .
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* Current users of this module :
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:43 +03:00
* iASL - Preprocessor ( constants and math expressions )
* iASL - Main parser , conversion of constants to integers
* iASL - Data Table Compiler parser ( constants and math expressions )
2017-09-20 05:00:36 +03:00
* interpreter - Implicit and explicit conversions , GPE method names
2017-09-20 05:00:49 +03:00
* interpreter - Repair code for return values from predefined names
2017-09-20 05:00:36 +03:00
* debugger - Command line input string conversion
2017-09-20 05:00:49 +03:00
* acpi_dump - ACPI table physical addresses
* acpi_exec - Support for namespace overrides
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* Notes concerning users of these interfaces :
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:49 +03:00
* acpi_gbl_integer_byte_width is used to set the 32 / 64 bit limit for explicit
* and implicit conversions . This global must be set to the proper width .
* For the core ACPICA code , the width depends on the DSDT version . For the
* acpi_ut_strtoul64 interface , all conversions are 64 bits . This interface is
* used primarily for iASL , where the default width is 64 bits for all parsers ,
* but error checking is performed later to flag cases where a 64 - bit constant
* is wrongly defined in a 32 - bit DSDT / SSDT .
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:49 +03:00
* In ACPI , the only place where octal numbers are supported is within
* the ASL language itself . This is implemented via the main acpi_ut_strtoul64
* interface . According the ACPI specification , there is no ACPI runtime
* support ( explicit / implicit ) for octal string conversions .
2016-09-07 09:14:30 +03:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*******************************************************************************
*
* FUNCTION : acpi_ut_strtoul64
*
2017-09-20 05:00:43 +03:00
* PARAMETERS : string - Null terminated input string ,
* must be a valid pointer
2016-09-07 09:14:30 +03:00
* return_value - Where the converted integer is
2017-09-20 05:00:36 +03:00
* returned . Must be a valid pointer
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:49 +03:00
* RETURN : Status and converted integer . Returns an exception on a
* 64 - bit numeric overflow
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:49 +03:00
* DESCRIPTION : Convert a string into an unsigned integer . Always performs a
* full 64 - bit conversion , regardless of the current global
2017-09-20 05:00:36 +03:00
* integer width . Supports Decimal , Hex , and Octal strings .
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* Current users of this function :
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:43 +03:00
* iASL - Preprocessor ( constants and math expressions )
* iASL - Main ASL parser , conversion of ASL constants to integers
* iASL - Data Table Compiler parser ( constants and math expressions )
2017-09-20 05:00:49 +03:00
* interpreter - Repair code for return values from predefined names
* acpi_dump - ACPI table physical addresses
* acpi_exec - Support for namespace overrides
2016-09-07 09:14:30 +03:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-09-20 05:00:36 +03:00
acpi_status acpi_ut_strtoul64 ( char * string , u64 * return_value )
2016-09-07 09:14:30 +03:00
{
acpi_status status = AE_OK ;
2017-09-20 05:00:49 +03:00
u8 original_bit_width ;
2017-09-20 05:00:36 +03:00
u32 base = 10 ; /* Default is decimal */
2016-09-07 09:14:30 +03:00
ACPI_FUNCTION_TRACE_STR ( ut_strtoul64 , string ) ;
* return_value = 0 ;
2017-09-20 05:00:43 +03:00
/* A NULL return string returns a value of zero */
2016-09-07 09:14:30 +03:00
if ( * string = = 0 ) {
return_ACPI_STATUS ( AE_OK ) ;
}
2017-09-20 05:00:49 +03:00
if ( ! acpi_ut_remove_whitespace ( & string ) ) {
return_ACPI_STATUS ( AE_OK ) ;
}
2016-09-07 09:14:30 +03:00
/*
2017-09-20 05:00:43 +03:00
* 1 ) Check for a hex constant . A " 0x " prefix indicates base 16.
2016-09-07 09:14:30 +03:00
*/
2017-09-20 05:00:36 +03:00
if ( acpi_ut_detect_hex_prefix ( & string ) ) {
2016-09-07 09:14:30 +03:00
base = 16 ;
}
2017-09-20 05:00:36 +03:00
/*
* 2 ) Check for an octal constant , defined to be a leading zero
2017-09-20 05:00:43 +03:00
* followed by sequence of octal digits ( 0 - 7 )
2017-09-20 05:00:36 +03:00
*/
else if ( acpi_ut_detect_octal_prefix ( & string ) ) {
base = 8 ;
2016-09-07 09:14:30 +03:00
}
2017-09-20 05:00:36 +03:00
if ( ! acpi_ut_remove_leading_zeros ( & string ) ) {
return_ACPI_STATUS ( AE_OK ) ; /* Return value 0 */
2016-09-07 09:14:30 +03:00
}
2017-09-20 05:00:36 +03:00
/*
2017-09-20 05:00:49 +03:00
* Force a full 64 - bit conversion . The caller ( usually iASL ) must
* check for a 32 - bit overflow later as necessary ( If current mode
* is 32 - bit , meaning a 32 - bit DSDT ) .
*/
original_bit_width = acpi_gbl_integer_bit_width ;
acpi_gbl_integer_bit_width = 64 ;
/*
* Perform the base 8 , 10 , or 16 conversion . A 64 - bit numeric overflow
* will return an exception ( to allow iASL to flag the statement ) .
2017-09-20 05:00:36 +03:00
*/
switch ( base ) {
case 8 :
status = acpi_ut_convert_octal_string ( string , return_value ) ;
break ;
case 10 :
status = acpi_ut_convert_decimal_string ( string , return_value ) ;
break ;
case 16 :
default :
2017-09-20 05:00:43 +03:00
status = acpi_ut_convert_hex_string ( string , return_value ) ;
2017-09-20 05:00:36 +03:00
break ;
2016-09-07 09:14:30 +03:00
}
2017-09-20 05:00:49 +03:00
/* Only possible exception from above is a 64-bit overflow */
acpi_gbl_integer_bit_width = original_bit_width ;
2016-09-07 09:14:30 +03:00
return_ACPI_STATUS ( status ) ;
}
/*******************************************************************************
*
2017-09-20 05:00:36 +03:00
* FUNCTION : acpi_ut_implicit_strtoul64
*
2017-09-20 05:00:43 +03:00
* PARAMETERS : string - Null terminated input string ,
* must be a valid pointer
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* RETURN : Converted integer
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* DESCRIPTION : Perform a 64 - bit conversion with restrictions placed upon
* an " implicit conversion " by the ACPI specification . Used by
* many ASL operators that require an integer operand , and support
* an automatic ( implicit ) conversion from a string operand
2017-09-20 05:00:43 +03:00
* to the final integer operand . The major restriction is that
* only hex strings are supported .
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2017-09-20 05:00:43 +03:00
* Base is always 16 , either with or without the 0 x prefix . Decimal and
* Octal strings are not supported , as per the ACPI specification .
2017-09-20 05:00:36 +03:00
*
* Examples ( both are hex values ) :
* Add ( " BA98 " , Arg0 , Local0 )
* Subtract ( " 0x12345678 " , Arg1 , Local1 )
*
2017-09-20 05:00:43 +03:00
* Conversion rules as extracted from the ACPI specification :
2017-09-20 05:00:36 +03:00
*
* The converted integer is initialized to the value zero .
2017-09-20 05:00:43 +03:00
* The ASCII string is always interpreted as a hexadecimal constant .
2017-09-20 05:00:36 +03:00
*
2017-09-20 05:00:43 +03:00
* 1 ) According to the ACPI specification , a " 0x " prefix is not allowed .
* However , ACPICA allows this as an ACPI extension on general
* principle . ( NO ERROR )
2017-09-20 05:00:36 +03:00
*
2017-09-20 05:00:43 +03:00
* 2 ) The conversion terminates when the size of an integer is reached
* ( 32 or 64 bits ) . There are no numeric overflow conditions . ( NO ERROR )
2017-09-20 05:00:36 +03:00
*
* 3 ) The first non - hex character terminates the conversion and returns
* the current accumulated value of the converted integer ( NO ERROR ) .
*
* 4 ) Conversion of a null ( zero - length ) string to an integer is
2017-09-20 05:00:43 +03:00
* technically not allowed . However , ACPICA allows this as an ACPI
* extension . The conversion returns the value 0. ( NO ERROR )
2017-09-20 05:00:36 +03:00
*
2017-09-20 05:00:43 +03:00
* NOTE : There are no error conditions returned by this function . At
2017-09-20 05:00:36 +03:00
* the minimum , a value of zero is returned .
*
* Current users of this function :
*
* interpreter - All runtime implicit conversions , as per ACPI specification
2017-09-20 05:00:43 +03:00
* iASL - Data Table Compiler parser ( constants and math expressions )
2016-09-07 09:14:30 +03:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-09-20 05:00:36 +03:00
u64 acpi_ut_implicit_strtoul64 ( char * string )
2016-09-07 09:14:30 +03:00
{
2017-09-20 05:00:36 +03:00
u64 converted_integer = 0 ;
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:36 +03:00
ACPI_FUNCTION_TRACE_STR ( ut_implicit_strtoul64 , string ) ;
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:49 +03:00
if ( ! acpi_ut_remove_whitespace ( & string ) ) {
return_VALUE ( 0 ) ;
}
2017-09-20 05:00:36 +03:00
/*
* Per the ACPI specification , only hexadecimal is supported for
* implicit conversions , and the " 0x " prefix is " not allowed " .
* However , allow a " 0x " prefix as an ACPI extension .
*/
2018-08-11 00:42:57 +03:00
acpi_ut_remove_hex_prefix ( & string ) ;
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:36 +03:00
if ( ! acpi_ut_remove_leading_zeros ( & string ) ) {
return_VALUE ( 0 ) ;
2016-09-07 09:14:30 +03:00
}
2017-09-20 05:00:36 +03:00
/*
* Ignore overflow as per the ACPI specification . This is implemented by
2017-09-20 05:00:49 +03:00
* ignoring the return status from the conversion function called below .
* On overflow , the input string is simply truncated .
2017-09-20 05:00:36 +03:00
*/
acpi_ut_convert_hex_string ( string , & converted_integer ) ;
return_VALUE ( converted_integer ) ;
2016-09-07 09:14:30 +03:00
}
/*******************************************************************************
*
2017-09-20 05:00:36 +03:00
* FUNCTION : acpi_ut_explicit_strtoul64
*
2017-09-20 05:00:43 +03:00
* PARAMETERS : string - Null terminated input string ,
* must be a valid pointer
2017-09-20 05:00:36 +03:00
*
* RETURN : Converted integer
*
* DESCRIPTION : Perform a 64 - bit conversion with the restrictions placed upon
* an " explicit conversion " by the ACPI specification . The
* main restriction is that only hex and decimal are supported .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2017-09-20 05:00:43 +03:00
* Base is either 10 ( default ) or 16 ( with 0 x prefix ) . Octal ( base 8 ) strings
* are not supported , as per the ACPI specification .
2017-09-20 05:00:36 +03:00
*
* Examples :
* to_integer ( " 1000 " ) Decimal
* to_integer ( " 0xABCD " ) Hex
*
2017-09-20 05:00:43 +03:00
* Conversion rules as extracted from the ACPI specification :
2017-09-20 05:00:36 +03:00
*
2017-09-20 05:00:43 +03:00
* 1 ) The input string is either a decimal or hexadecimal numeric string .
2017-09-20 05:00:36 +03:00
* A hex value must be prefixed by " 0x " or it is interpreted as decimal .
*
* 2 ) The value must not exceed the maximum of an integer value
* ( 32 or 64 bits ) . The ACPI specification states the behavior is
* " unpredictable " , so ACPICA matches the behavior of the implicit
* conversion case . There are no numeric overflow conditions . ( NO ERROR )
*
2017-09-20 05:00:43 +03:00
* 3 ) Behavior on the first non - hex character is not defined by the ACPI
2017-09-20 05:00:36 +03:00
* specification ( for the to_integer operator ) , so ACPICA matches the
* behavior of the implicit conversion case . It terminates the
* conversion and returns the current accumulated value of the converted
* integer . ( NO ERROR )
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* 4 ) Conversion of a null ( zero - length ) string to an integer is
2017-09-20 05:00:43 +03:00
* technically not allowed . However , ACPICA allows this as an ACPI
* extension . The conversion returns the value 0. ( NO ERROR )
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:43 +03:00
* NOTE : There are no error conditions returned by this function . At the
* minimum , a value of zero is returned .
2016-09-07 09:14:30 +03:00
*
2017-09-20 05:00:36 +03:00
* Current users of this function :
*
* interpreter - Runtime ASL to_integer operator , as per the ACPI specification
2016-09-07 09:14:30 +03:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-09-20 05:00:36 +03:00
u64 acpi_ut_explicit_strtoul64 ( char * string )
2016-09-07 09:14:30 +03:00
{
2017-09-20 05:00:36 +03:00
u64 converted_integer = 0 ;
u32 base = 10 ; /* Default is decimal */
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:36 +03:00
ACPI_FUNCTION_TRACE_STR ( ut_explicit_strtoul64 , string ) ;
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:49 +03:00
if ( ! acpi_ut_remove_whitespace ( & string ) ) {
return_VALUE ( 0 ) ;
}
2017-09-20 05:00:36 +03:00
/*
* Only Hex and Decimal are supported , as per the ACPI specification .
2017-09-20 05:00:43 +03:00
* A " 0x " prefix indicates hex ; otherwise decimal is assumed .
2017-09-20 05:00:36 +03:00
*/
if ( acpi_ut_detect_hex_prefix ( & string ) ) {
base = 16 ;
}
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:36 +03:00
if ( ! acpi_ut_remove_leading_zeros ( & string ) ) {
return_VALUE ( 0 ) ;
}
2016-09-07 09:14:30 +03:00
2017-09-20 05:00:36 +03:00
/*
* Ignore overflow as per the ACPI specification . This is implemented by
2017-09-20 05:00:49 +03:00
* ignoring the return status from the conversion functions called below .
* On overflow , the input string is simply truncated .
2017-09-20 05:00:36 +03:00
*/
switch ( base ) {
case 10 :
default :
acpi_ut_convert_decimal_string ( string , & converted_integer ) ;
break ;
case 16 :
acpi_ut_convert_hex_string ( string , & converted_integer ) ;
break ;
2016-09-07 09:14:30 +03:00
}
2017-09-20 05:00:36 +03:00
return_VALUE ( converted_integer ) ;
2016-09-07 09:14:30 +03:00
}