1 /*******************************************************************************
3 * Module Name: utstrsuppt - Support functions for string-to-integer conversion
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2018, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utstrsuppt")
51 /* Local prototypes */
55 UINT64
*AccumulatedValue
,
60 AcpiUtStrtoulMultiply64 (
72 /*******************************************************************************
74 * FUNCTION: AcpiUtConvertOctalString
76 * PARAMETERS: String - Null terminated input string
77 * ReturnValuePtr - Where the converted value is returned
79 * RETURN: Status and 64-bit converted integer
81 * DESCRIPTION: Performs a base 8 conversion of the input string to an
82 * integer value, either 32 or 64 bits.
84 * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777
85 * Maximum 32-bit unsigned octal value is 037777777777
87 ******************************************************************************/
90 AcpiUtConvertOctalString (
92 UINT64
*ReturnValuePtr
)
94 UINT64 AccumulatedValue
= 0;
95 ACPI_STATUS Status
= AE_OK
;
98 /* Convert each ASCII byte in the input string */
102 /* Character must be ASCII 0-7, otherwise terminate with no error */
104 if (!(ACPI_IS_OCTAL_DIGIT (*String
)))
109 /* Convert and insert this octal digit into the accumulator */
111 Status
= AcpiUtInsertDigit (&AccumulatedValue
, 8, *String
);
112 if (ACPI_FAILURE (Status
))
114 Status
= AE_OCTAL_OVERFLOW
;
121 /* Always return the value that has been accumulated */
123 *ReturnValuePtr
= AccumulatedValue
;
128 /*******************************************************************************
130 * FUNCTION: AcpiUtConvertDecimalString
132 * PARAMETERS: String - Null terminated input string
133 * ReturnValuePtr - Where the converted value is returned
135 * RETURN: Status and 64-bit converted integer
137 * DESCRIPTION: Performs a base 10 conversion of the input string to an
138 * integer value, either 32 or 64 bits.
140 * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615
141 * Maximum 32-bit unsigned decimal value is 4294967295
143 ******************************************************************************/
146 AcpiUtConvertDecimalString (
148 UINT64
*ReturnValuePtr
)
150 UINT64 AccumulatedValue
= 0;
151 ACPI_STATUS Status
= AE_OK
;
154 /* Convert each ASCII byte in the input string */
158 /* Character must be ASCII 0-9, otherwise terminate with no error */
160 if (!isdigit (*String
))
165 /* Convert and insert this decimal digit into the accumulator */
167 Status
= AcpiUtInsertDigit (&AccumulatedValue
, 10, *String
);
168 if (ACPI_FAILURE (Status
))
170 Status
= AE_DECIMAL_OVERFLOW
;
177 /* Always return the value that has been accumulated */
179 *ReturnValuePtr
= AccumulatedValue
;
184 /*******************************************************************************
186 * FUNCTION: AcpiUtConvertHexString
188 * PARAMETERS: String - Null terminated input string
189 * ReturnValuePtr - Where the converted value is returned
191 * RETURN: Status and 64-bit converted integer
193 * DESCRIPTION: Performs a base 16 conversion of the input string to an
194 * integer value, either 32 or 64 bits.
196 * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
197 * Maximum 32-bit unsigned hex value is 0xFFFFFFFF
199 ******************************************************************************/
202 AcpiUtConvertHexString (
204 UINT64
*ReturnValuePtr
)
206 UINT64 AccumulatedValue
= 0;
207 ACPI_STATUS Status
= AE_OK
;
210 /* Convert each ASCII byte in the input string */
214 /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */
216 if (!isxdigit (*String
))
221 /* Convert and insert this hex digit into the accumulator */
223 Status
= AcpiUtInsertDigit (&AccumulatedValue
, 16, *String
);
224 if (ACPI_FAILURE (Status
))
226 Status
= AE_HEX_OVERFLOW
;
233 /* Always return the value that has been accumulated */
235 *ReturnValuePtr
= AccumulatedValue
;
240 /*******************************************************************************
242 * FUNCTION: AcpiUtRemoveLeadingZeros
244 * PARAMETERS: String - Pointer to input ASCII string
246 * RETURN: Next character after any leading zeros. This character may be
247 * used by the caller to detect end-of-string.
249 * DESCRIPTION: Remove any leading zeros in the input string. Return the
250 * next character after the final ASCII zero to enable the caller
251 * to check for the end of the string (NULL terminator).
253 ******************************************************************************/
256 AcpiUtRemoveLeadingZeros (
260 while (**String
== ACPI_ASCII_ZERO
)
269 /*******************************************************************************
271 * FUNCTION: AcpiUtRemoveWhitespace
273 * PARAMETERS: String - Pointer to input ASCII string
275 * RETURN: Next character after any whitespace. This character may be
276 * used by the caller to detect end-of-string.
278 * DESCRIPTION: Remove any leading whitespace in the input string. Return the
279 * next character after the final ASCII zero to enable the caller
280 * to check for the end of the string (NULL terminator).
282 ******************************************************************************/
285 AcpiUtRemoveWhitespace (
289 while (isspace ((UINT8
) **String
))
298 /*******************************************************************************
300 * FUNCTION: AcpiUtDetectHexPrefix
302 * PARAMETERS: String - Pointer to input ASCII string
304 * RETURN: TRUE if a "0x" prefix was found at the start of the string
306 * DESCRIPTION: Detect and remove a hex "0x" prefix
308 ******************************************************************************/
311 AcpiUtDetectHexPrefix (
314 char *InitialPosition
= *String
;
316 AcpiUtRemoveHexPrefix (String
);
317 if (*String
!= InitialPosition
)
319 return (TRUE
); /* String is past leading 0x */
322 return (FALSE
); /* Not a hex string */
326 /*******************************************************************************
328 * FUNCTION: AcpiUtRemoveHexPrefix
330 * PARAMETERS: String - Pointer to input ASCII string
334 * DESCRIPTION: Remove a hex "0x" prefix
336 ******************************************************************************/
339 AcpiUtRemoveHexPrefix (
342 if ((**String
== ACPI_ASCII_ZERO
) &&
343 (tolower ((int) *(*String
+ 1)) == 'x'))
345 *String
+= 2; /* Go past the leading 0x */
350 /*******************************************************************************
352 * FUNCTION: AcpiUtDetectOctalPrefix
354 * PARAMETERS: String - Pointer to input ASCII string
356 * RETURN: True if an octal "0" prefix was found at the start of the
359 * DESCRIPTION: Detect and remove an octal prefix (zero)
361 ******************************************************************************/
364 AcpiUtDetectOctalPrefix (
368 if (**String
== ACPI_ASCII_ZERO
)
370 *String
+= 1; /* Go past the leading 0 */
374 return (FALSE
); /* Not an octal string */
378 /*******************************************************************************
380 * FUNCTION: AcpiUtInsertDigit
382 * PARAMETERS: AccumulatedValue - Current value of the integer value
383 * accumulator. The new value is
385 * Base - Radix, either 8/10/16
386 * AsciiDigit - ASCII single digit to be inserted
388 * RETURN: Status and result of the convert/insert operation. The only
389 * possible returned exception code is numeric overflow of
390 * either the multiply or add conversion operations.
392 * DESCRIPTION: Generic conversion and insertion function for all bases:
394 * 1) Multiply the current accumulated/converted value by the
395 * base in order to make room for the new character.
397 * 2) Convert the new character to binary and add it to the
398 * current accumulated value.
400 * Note: The only possible exception indicates an integer
401 * overflow (AE_NUMERIC_OVERFLOW)
403 ******************************************************************************/
407 UINT64
*AccumulatedValue
,
415 /* Make room in the accumulated value for the incoming digit */
417 Status
= AcpiUtStrtoulMultiply64 (*AccumulatedValue
, Base
, &Product
);
418 if (ACPI_FAILURE (Status
))
423 /* Add in the new digit, and store the sum to the accumulated value */
425 Status
= AcpiUtStrtoulAdd64 (Product
, AcpiUtAsciiCharToHex (AsciiDigit
),
432 /*******************************************************************************
434 * FUNCTION: AcpiUtStrtoulMultiply64
436 * PARAMETERS: Multiplicand - Current accumulated converted integer
438 * OutProduct - Where the product is returned
440 * RETURN: Status and 64-bit product
442 * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
443 * well as 32-bit overflow if necessary (if the current global
444 * integer width is 32).
446 ******************************************************************************/
449 AcpiUtStrtoulMultiply64 (
458 /* Exit if either operand is zero */
461 if (!Multiplicand
|| !Base
)
467 * Check for 64-bit overflow before the actual multiplication.
469 * Notes: 64-bit division is often not supported on 32-bit platforms
470 * (it requires a library function), Therefore ACPICA has a local
471 * 64-bit divide function. Also, Multiplier is currently only used
472 * as the radix (8/10/16), to the 64/32 divide will always work.
474 AcpiUtShortDivide (ACPI_UINT64_MAX
, Base
, &Quotient
, NULL
);
475 if (Multiplicand
> Quotient
)
477 return (AE_NUMERIC_OVERFLOW
);
480 Product
= Multiplicand
* Base
;
482 /* Check for 32-bit overflow if necessary */
484 if ((AcpiGbl_IntegerBitWidth
== 32) && (Product
> ACPI_UINT32_MAX
))
486 return (AE_NUMERIC_OVERFLOW
);
489 *OutProduct
= Product
;
494 /*******************************************************************************
496 * FUNCTION: AcpiUtStrtoulAdd64
498 * PARAMETERS: Addend1 - Current accumulated converted integer
499 * Digit - New hex value/char
500 * OutSum - Where sum is returned (Accumulator)
502 * RETURN: Status and 64-bit sum
504 * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
505 * well as 32-bit overflow if necessary (if the current global
506 * integer width is 32).
508 ******************************************************************************/
519 /* Check for 64-bit overflow before the actual addition */
521 if ((Addend1
> 0) && (Digit
> (ACPI_UINT64_MAX
- Addend1
)))
523 return (AE_NUMERIC_OVERFLOW
);
526 Sum
= Addend1
+ Digit
;
528 /* Check for 32-bit overflow if necessary */
530 if ((AcpiGbl_IntegerBitWidth
== 32) && (Sum
> ACPI_UINT32_MAX
))
532 return (AE_NUMERIC_OVERFLOW
);