^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: utstrsuppt - Support functions for string-to-integer conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define _COMPONENT ACPI_UTILITIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) ACPI_MODULE_NAME("utstrsuppt")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * FUNCTION: acpi_ut_convert_octal_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * PARAMETERS: string - Null terminated input string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * return_value_ptr - Where the converted value is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * RETURN: Status and 64-bit converted integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * DESCRIPTION: Performs a base 8 conversion of the input string to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * integer value, either 32 or 64 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Maximum 32-bit unsigned octal value is 037777777777
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u64 accumulated_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Convert each ASCII byte in the input string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) while (*string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Character must be ASCII 0-7, otherwise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * 1) Runtime: terminate with no error, per the ACPI spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * 2) Compiler: return an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!(ACPI_IS_OCTAL_DIGIT(*string))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) status = AE_BAD_OCTAL_CONSTANT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Convert and insert this octal digit into the accumulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) status = acpi_ut_insert_digit(&accumulated_value, 8, *string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) status = AE_OCTAL_OVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Always return the value that has been accumulated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *return_value_ptr = accumulated_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * FUNCTION: acpi_ut_convert_decimal_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * PARAMETERS: string - Null terminated input string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * return_value_ptr - Where the converted value is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * RETURN: Status and 64-bit converted integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * DESCRIPTION: Performs a base 10 conversion of the input string to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * integer value, either 32 or 64 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Maximum 32-bit unsigned decimal value is 4294967295
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u64 accumulated_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Convert each ASCII byte in the input string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) while (*string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Character must be ASCII 0-9, otherwise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * 1) Runtime: terminate with no error, per the ACPI spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * 2) Compiler: return an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!isdigit(*string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) status = AE_BAD_DECIMAL_CONSTANT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Convert and insert this decimal digit into the accumulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) status = acpi_ut_insert_digit(&accumulated_value, 10, *string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) status = AE_DECIMAL_OVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Always return the value that has been accumulated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *return_value_ptr = accumulated_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * FUNCTION: acpi_ut_convert_hex_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * PARAMETERS: string - Null terminated input string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * return_value_ptr - Where the converted value is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * RETURN: Status and 64-bit converted integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * DESCRIPTION: Performs a base 16 conversion of the input string to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * integer value, either 32 or 64 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Maximum 32-bit unsigned hex value is 0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u64 accumulated_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Convert each ASCII byte in the input string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) while (*string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Character must be ASCII A-F, a-f, or 0-9, otherwise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * 1) Runtime: terminate with no error, per the ACPI spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * 2) Compiler: return an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!isxdigit(*string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #ifdef ACPI_ASL_COMPILER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) status = AE_BAD_HEX_CONSTANT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Convert and insert this hex digit into the accumulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) status = acpi_ut_insert_digit(&accumulated_value, 16, *string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) status = AE_HEX_OVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Always return the value that has been accumulated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *return_value_ptr = accumulated_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * FUNCTION: acpi_ut_remove_leading_zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * PARAMETERS: string - Pointer to input ASCII string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * RETURN: Next character after any leading zeros. This character may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * used by the caller to detect end-of-string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * DESCRIPTION: Remove any leading zeros in the input string. Return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * next character after the final ASCII zero to enable the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * to check for the end of the string (NULL terminator).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) char acpi_ut_remove_leading_zeros(char **string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) while (**string == ACPI_ASCII_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *string += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return (**string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * FUNCTION: acpi_ut_remove_whitespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * PARAMETERS: string - Pointer to input ASCII string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * RETURN: Next character after any whitespace. This character may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * used by the caller to detect end-of-string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * DESCRIPTION: Remove any leading whitespace in the input string. Return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * next character after the final ASCII zero to enable the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * to check for the end of the string (NULL terminator).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) char acpi_ut_remove_whitespace(char **string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) while (isspace((u8)**string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *string += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return (**string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * FUNCTION: acpi_ut_detect_hex_prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * PARAMETERS: string - Pointer to input ASCII string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * RETURN: TRUE if a "0x" prefix was found at the start of the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * DESCRIPTION: Detect and remove a hex "0x" prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u8 acpi_ut_detect_hex_prefix(char **string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) char *initial_position = *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) acpi_ut_remove_hex_prefix(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (*string != initial_position) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return (TRUE); /* String is past leading 0x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return (FALSE); /* Not a hex string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * FUNCTION: acpi_ut_remove_hex_prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * PARAMETERS: string - Pointer to input ASCII string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * RETURN: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * DESCRIPTION: Remove a hex "0x" prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) void acpi_ut_remove_hex_prefix(char **string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if ((**string == ACPI_ASCII_ZERO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) (tolower((int)*(*string + 1)) == 'x')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *string += 2; /* Go past the leading 0x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * FUNCTION: acpi_ut_detect_octal_prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * PARAMETERS: string - Pointer to input ASCII string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * RETURN: True if an octal "0" prefix was found at the start of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * DESCRIPTION: Detect and remove an octal prefix (zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u8 acpi_ut_detect_octal_prefix(char **string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (**string == ACPI_ASCII_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *string += 1; /* Go past the leading 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return (TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return (FALSE); /* Not an octal string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * FUNCTION: acpi_ut_insert_digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * PARAMETERS: accumulated_value - Current value of the integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * accumulator. The new value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * returned here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * base - Radix, either 8/10/16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * ascii_digit - ASCII single digit to be inserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * RETURN: Status and result of the convert/insert operation. The only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * possible returned exception code is numeric overflow of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * either the multiply or add conversion operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * DESCRIPTION: Generic conversion and insertion function for all bases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * 1) Multiply the current accumulated/converted value by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * base in order to make room for the new character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * 2) Convert the new character to binary and add it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * current accumulated value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Note: The only possible exception indicates an integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * overflow (AE_NUMERIC_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u64 product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* Make room in the accumulated value for the incoming digit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) status = acpi_ut_strtoul_multiply64(*accumulated_value, base, &product);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Add in the new digit, and store the sum to the accumulated value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) acpi_ut_strtoul_add64(product,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) acpi_ut_ascii_char_to_hex(ascii_digit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) accumulated_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * FUNCTION: acpi_ut_strtoul_multiply64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * PARAMETERS: multiplicand - Current accumulated converted integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * base - Base/Radix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * out_product - Where the product is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * RETURN: Status and 64-bit product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * well as 32-bit overflow if necessary (if the current global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * integer width is 32).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u64 product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u64 quotient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Exit if either operand is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *out_product = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!multiplicand || !base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Check for 64-bit overflow before the actual multiplication.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * Notes: 64-bit division is often not supported on 32-bit platforms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * (it requires a library function), Therefore ACPICA has a local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * 64-bit divide function. Also, Multiplier is currently only used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * as the radix (8/10/16), to the 64/32 divide will always work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) acpi_ut_short_divide(ACPI_UINT64_MAX, base, "ient, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (multiplicand > quotient) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return (AE_NUMERIC_OVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) product = multiplicand * base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* Check for 32-bit overflow if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if ((acpi_gbl_integer_bit_width == 32) && (product > ACPI_UINT32_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return (AE_NUMERIC_OVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *out_product = product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * FUNCTION: acpi_ut_strtoul_add64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * PARAMETERS: addend1 - Current accumulated converted integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * digit - New hex value/char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * out_sum - Where sum is returned (Accumulator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * RETURN: Status and 64-bit sum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * well as 32-bit overflow if necessary (if the current global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * integer width is 32).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) u64 sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Check for 64-bit overflow before the actual addition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if ((addend1 > 0) && (digit > (ACPI_UINT64_MAX - addend1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return (AE_NUMERIC_OVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) sum = addend1 + digit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* Check for 32-bit overflow if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if ((acpi_gbl_integer_bit_width == 32) && (sum > ACPI_UINT32_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return (AE_NUMERIC_OVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *out_sum = sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }