[ACPICA] Update to version 20190108. CORE-15593
[reactos.git] / drivers / bus / acpi / acpica / utilities / utstrsuppt.c
1 /*******************************************************************************
2 *
3 * Module Name: utstrsuppt - Support functions for string-to-integer conversion
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
25 *
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.
29 *
30 * NO WARRANTY
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.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utstrsuppt")
49
50
51 /* Local prototypes */
52
53 static ACPI_STATUS
54 AcpiUtInsertDigit (
55 UINT64 *AccumulatedValue,
56 UINT32 Base,
57 int AsciiDigit);
58
59 static ACPI_STATUS
60 AcpiUtStrtoulMultiply64 (
61 UINT64 Multiplicand,
62 UINT32 Base,
63 UINT64 *OutProduct);
64
65 static ACPI_STATUS
66 AcpiUtStrtoulAdd64 (
67 UINT64 Addend1,
68 UINT32 Digit,
69 UINT64 *OutSum);
70
71
72 /*******************************************************************************
73 *
74 * FUNCTION: AcpiUtConvertOctalString
75 *
76 * PARAMETERS: String - Null terminated input string
77 * ReturnValuePtr - Where the converted value is returned
78 *
79 * RETURN: Status and 64-bit converted integer
80 *
81 * DESCRIPTION: Performs a base 8 conversion of the input string to an
82 * integer value, either 32 or 64 bits.
83 *
84 * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777
85 * Maximum 32-bit unsigned octal value is 037777777777
86 *
87 ******************************************************************************/
88
89 ACPI_STATUS
90 AcpiUtConvertOctalString (
91 char *String,
92 UINT64 *ReturnValuePtr)
93 {
94 UINT64 AccumulatedValue = 0;
95 ACPI_STATUS Status = AE_OK;
96
97
98 /* Convert each ASCII byte in the input string */
99
100 while (*String)
101 {
102 /* Character must be ASCII 0-7, otherwise terminate with no error */
103
104 if (!(ACPI_IS_OCTAL_DIGIT (*String)))
105 {
106 break;
107 }
108
109 /* Convert and insert this octal digit into the accumulator */
110
111 Status = AcpiUtInsertDigit (&AccumulatedValue, 8, *String);
112 if (ACPI_FAILURE (Status))
113 {
114 Status = AE_OCTAL_OVERFLOW;
115 break;
116 }
117
118 String++;
119 }
120
121 /* Always return the value that has been accumulated */
122
123 *ReturnValuePtr = AccumulatedValue;
124 return (Status);
125 }
126
127
128 /*******************************************************************************
129 *
130 * FUNCTION: AcpiUtConvertDecimalString
131 *
132 * PARAMETERS: String - Null terminated input string
133 * ReturnValuePtr - Where the converted value is returned
134 *
135 * RETURN: Status and 64-bit converted integer
136 *
137 * DESCRIPTION: Performs a base 10 conversion of the input string to an
138 * integer value, either 32 or 64 bits.
139 *
140 * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615
141 * Maximum 32-bit unsigned decimal value is 4294967295
142 *
143 ******************************************************************************/
144
145 ACPI_STATUS
146 AcpiUtConvertDecimalString (
147 char *String,
148 UINT64 *ReturnValuePtr)
149 {
150 UINT64 AccumulatedValue = 0;
151 ACPI_STATUS Status = AE_OK;
152
153
154 /* Convert each ASCII byte in the input string */
155
156 while (*String)
157 {
158 /* Character must be ASCII 0-9, otherwise terminate with no error */
159
160 if (!isdigit (*String))
161 {
162 break;
163 }
164
165 /* Convert and insert this decimal digit into the accumulator */
166
167 Status = AcpiUtInsertDigit (&AccumulatedValue, 10, *String);
168 if (ACPI_FAILURE (Status))
169 {
170 Status = AE_DECIMAL_OVERFLOW;
171 break;
172 }
173
174 String++;
175 }
176
177 /* Always return the value that has been accumulated */
178
179 *ReturnValuePtr = AccumulatedValue;
180 return (Status);
181 }
182
183
184 /*******************************************************************************
185 *
186 * FUNCTION: AcpiUtConvertHexString
187 *
188 * PARAMETERS: String - Null terminated input string
189 * ReturnValuePtr - Where the converted value is returned
190 *
191 * RETURN: Status and 64-bit converted integer
192 *
193 * DESCRIPTION: Performs a base 16 conversion of the input string to an
194 * integer value, either 32 or 64 bits.
195 *
196 * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
197 * Maximum 32-bit unsigned hex value is 0xFFFFFFFF
198 *
199 ******************************************************************************/
200
201 ACPI_STATUS
202 AcpiUtConvertHexString (
203 char *String,
204 UINT64 *ReturnValuePtr)
205 {
206 UINT64 AccumulatedValue = 0;
207 ACPI_STATUS Status = AE_OK;
208
209
210 /* Convert each ASCII byte in the input string */
211
212 while (*String)
213 {
214 /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */
215
216 if (!isxdigit (*String))
217 {
218 break;
219 }
220
221 /* Convert and insert this hex digit into the accumulator */
222
223 Status = AcpiUtInsertDigit (&AccumulatedValue, 16, *String);
224 if (ACPI_FAILURE (Status))
225 {
226 Status = AE_HEX_OVERFLOW;
227 break;
228 }
229
230 String++;
231 }
232
233 /* Always return the value that has been accumulated */
234
235 *ReturnValuePtr = AccumulatedValue;
236 return (Status);
237 }
238
239
240 /*******************************************************************************
241 *
242 * FUNCTION: AcpiUtRemoveLeadingZeros
243 *
244 * PARAMETERS: String - Pointer to input ASCII string
245 *
246 * RETURN: Next character after any leading zeros. This character may be
247 * used by the caller to detect end-of-string.
248 *
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).
252 *
253 ******************************************************************************/
254
255 char
256 AcpiUtRemoveLeadingZeros (
257 char **String)
258 {
259
260 while (**String == ACPI_ASCII_ZERO)
261 {
262 *String += 1;
263 }
264
265 return (**String);
266 }
267
268
269 /*******************************************************************************
270 *
271 * FUNCTION: AcpiUtRemoveWhitespace
272 *
273 * PARAMETERS: String - Pointer to input ASCII string
274 *
275 * RETURN: Next character after any whitespace. This character may be
276 * used by the caller to detect end-of-string.
277 *
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).
281 *
282 ******************************************************************************/
283
284 char
285 AcpiUtRemoveWhitespace (
286 char **String)
287 {
288
289 while (isspace ((UINT8) **String))
290 {
291 *String += 1;
292 }
293
294 return (**String);
295 }
296
297
298 /*******************************************************************************
299 *
300 * FUNCTION: AcpiUtDetectHexPrefix
301 *
302 * PARAMETERS: String - Pointer to input ASCII string
303 *
304 * RETURN: TRUE if a "0x" prefix was found at the start of the string
305 *
306 * DESCRIPTION: Detect and remove a hex "0x" prefix
307 *
308 ******************************************************************************/
309
310 BOOLEAN
311 AcpiUtDetectHexPrefix (
312 char **String)
313 {
314 char *InitialPosition = *String;
315
316 AcpiUtRemoveHexPrefix (String);
317 if (*String != InitialPosition)
318 {
319 return (TRUE); /* String is past leading 0x */
320 }
321
322 return (FALSE); /* Not a hex string */
323 }
324
325
326 /*******************************************************************************
327 *
328 * FUNCTION: AcpiUtRemoveHexPrefix
329 *
330 * PARAMETERS: String - Pointer to input ASCII string
331 *
332 * RETURN: none
333 *
334 * DESCRIPTION: Remove a hex "0x" prefix
335 *
336 ******************************************************************************/
337
338 void
339 AcpiUtRemoveHexPrefix (
340 char **String)
341 {
342 if ((**String == ACPI_ASCII_ZERO) &&
343 (tolower ((int) *(*String + 1)) == 'x'))
344 {
345 *String += 2; /* Go past the leading 0x */
346 }
347 }
348
349
350 /*******************************************************************************
351 *
352 * FUNCTION: AcpiUtDetectOctalPrefix
353 *
354 * PARAMETERS: String - Pointer to input ASCII string
355 *
356 * RETURN: True if an octal "0" prefix was found at the start of the
357 * string
358 *
359 * DESCRIPTION: Detect and remove an octal prefix (zero)
360 *
361 ******************************************************************************/
362
363 BOOLEAN
364 AcpiUtDetectOctalPrefix (
365 char **String)
366 {
367
368 if (**String == ACPI_ASCII_ZERO)
369 {
370 *String += 1; /* Go past the leading 0 */
371 return (TRUE);
372 }
373
374 return (FALSE); /* Not an octal string */
375 }
376
377
378 /*******************************************************************************
379 *
380 * FUNCTION: AcpiUtInsertDigit
381 *
382 * PARAMETERS: AccumulatedValue - Current value of the integer value
383 * accumulator. The new value is
384 * returned here.
385 * Base - Radix, either 8/10/16
386 * AsciiDigit - ASCII single digit to be inserted
387 *
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.
391 *
392 * DESCRIPTION: Generic conversion and insertion function for all bases:
393 *
394 * 1) Multiply the current accumulated/converted value by the
395 * base in order to make room for the new character.
396 *
397 * 2) Convert the new character to binary and add it to the
398 * current accumulated value.
399 *
400 * Note: The only possible exception indicates an integer
401 * overflow (AE_NUMERIC_OVERFLOW)
402 *
403 ******************************************************************************/
404
405 static ACPI_STATUS
406 AcpiUtInsertDigit (
407 UINT64 *AccumulatedValue,
408 UINT32 Base,
409 int AsciiDigit)
410 {
411 ACPI_STATUS Status;
412 UINT64 Product;
413
414
415 /* Make room in the accumulated value for the incoming digit */
416
417 Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product);
418 if (ACPI_FAILURE (Status))
419 {
420 return (Status);
421 }
422
423 /* Add in the new digit, and store the sum to the accumulated value */
424
425 Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit),
426 AccumulatedValue);
427
428 return (Status);
429 }
430
431
432 /*******************************************************************************
433 *
434 * FUNCTION: AcpiUtStrtoulMultiply64
435 *
436 * PARAMETERS: Multiplicand - Current accumulated converted integer
437 * Base - Base/Radix
438 * OutProduct - Where the product is returned
439 *
440 * RETURN: Status and 64-bit product
441 *
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).
445 *
446 ******************************************************************************/
447
448 static ACPI_STATUS
449 AcpiUtStrtoulMultiply64 (
450 UINT64 Multiplicand,
451 UINT32 Base,
452 UINT64 *OutProduct)
453 {
454 UINT64 Product;
455 UINT64 Quotient;
456
457
458 /* Exit if either operand is zero */
459
460 *OutProduct = 0;
461 if (!Multiplicand || !Base)
462 {
463 return (AE_OK);
464 }
465
466 /*
467 * Check for 64-bit overflow before the actual multiplication.
468 *
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.
473 */
474 AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL);
475 if (Multiplicand > Quotient)
476 {
477 return (AE_NUMERIC_OVERFLOW);
478 }
479
480 Product = Multiplicand * Base;
481
482 /* Check for 32-bit overflow if necessary */
483
484 if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX))
485 {
486 return (AE_NUMERIC_OVERFLOW);
487 }
488
489 *OutProduct = Product;
490 return (AE_OK);
491 }
492
493
494 /*******************************************************************************
495 *
496 * FUNCTION: AcpiUtStrtoulAdd64
497 *
498 * PARAMETERS: Addend1 - Current accumulated converted integer
499 * Digit - New hex value/char
500 * OutSum - Where sum is returned (Accumulator)
501 *
502 * RETURN: Status and 64-bit sum
503 *
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).
507 *
508 ******************************************************************************/
509
510 static ACPI_STATUS
511 AcpiUtStrtoulAdd64 (
512 UINT64 Addend1,
513 UINT32 Digit,
514 UINT64 *OutSum)
515 {
516 UINT64 Sum;
517
518
519 /* Check for 64-bit overflow before the actual addition */
520
521 if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1)))
522 {
523 return (AE_NUMERIC_OVERFLOW);
524 }
525
526 Sum = Addend1 + Digit;
527
528 /* Check for 32-bit overflow if necessary */
529
530 if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX))
531 {
532 return (AE_NUMERIC_OVERFLOW);
533 }
534
535 *OutSum = Sum;
536 return (AE_OK);
537 }