[ACPICA] Update to version 20171215. CORE-15222
[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 - 2017, 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
315 if ((**String == ACPI_ASCII_ZERO) &&
316 (tolower ((int) *(*String + 1)) == 'x'))
317 {
318 *String += 2; /* Go past the leading 0x */
319 return (TRUE);
320 }
321
322 return (FALSE); /* Not a hex string */
323 }
324
325
326 /*******************************************************************************
327 *
328 * FUNCTION: AcpiUtDetectOctalPrefix
329 *
330 * PARAMETERS: String - Pointer to input ASCII string
331 *
332 * RETURN: True if an octal "0" prefix was found at the start of the
333 * string
334 *
335 * DESCRIPTION: Detect and remove an octal prefix (zero)
336 *
337 ******************************************************************************/
338
339 BOOLEAN
340 AcpiUtDetectOctalPrefix (
341 char **String)
342 {
343
344 if (**String == ACPI_ASCII_ZERO)
345 {
346 *String += 1; /* Go past the leading 0 */
347 return (TRUE);
348 }
349
350 return (FALSE); /* Not an octal string */
351 }
352
353
354 /*******************************************************************************
355 *
356 * FUNCTION: AcpiUtInsertDigit
357 *
358 * PARAMETERS: AccumulatedValue - Current value of the integer value
359 * accumulator. The new value is
360 * returned here.
361 * Base - Radix, either 8/10/16
362 * AsciiDigit - ASCII single digit to be inserted
363 *
364 * RETURN: Status and result of the convert/insert operation. The only
365 * possible returned exception code is numeric overflow of
366 * either the multiply or add conversion operations.
367 *
368 * DESCRIPTION: Generic conversion and insertion function for all bases:
369 *
370 * 1) Multiply the current accumulated/converted value by the
371 * base in order to make room for the new character.
372 *
373 * 2) Convert the new character to binary and add it to the
374 * current accumulated value.
375 *
376 * Note: The only possible exception indicates an integer
377 * overflow (AE_NUMERIC_OVERFLOW)
378 *
379 ******************************************************************************/
380
381 static ACPI_STATUS
382 AcpiUtInsertDigit (
383 UINT64 *AccumulatedValue,
384 UINT32 Base,
385 int AsciiDigit)
386 {
387 ACPI_STATUS Status;
388 UINT64 Product;
389
390
391 /* Make room in the accumulated value for the incoming digit */
392
393 Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product);
394 if (ACPI_FAILURE (Status))
395 {
396 return (Status);
397 }
398
399 /* Add in the new digit, and store the sum to the accumulated value */
400
401 Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit),
402 AccumulatedValue);
403
404 return (Status);
405 }
406
407
408 /*******************************************************************************
409 *
410 * FUNCTION: AcpiUtStrtoulMultiply64
411 *
412 * PARAMETERS: Multiplicand - Current accumulated converted integer
413 * Base - Base/Radix
414 * OutProduct - Where the product is returned
415 *
416 * RETURN: Status and 64-bit product
417 *
418 * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
419 * well as 32-bit overflow if necessary (if the current global
420 * integer width is 32).
421 *
422 ******************************************************************************/
423
424 static ACPI_STATUS
425 AcpiUtStrtoulMultiply64 (
426 UINT64 Multiplicand,
427 UINT32 Base,
428 UINT64 *OutProduct)
429 {
430 UINT64 Product;
431 UINT64 Quotient;
432
433
434 /* Exit if either operand is zero */
435
436 *OutProduct = 0;
437 if (!Multiplicand || !Base)
438 {
439 return (AE_OK);
440 }
441
442 /*
443 * Check for 64-bit overflow before the actual multiplication.
444 *
445 * Notes: 64-bit division is often not supported on 32-bit platforms
446 * (it requires a library function), Therefore ACPICA has a local
447 * 64-bit divide function. Also, Multiplier is currently only used
448 * as the radix (8/10/16), to the 64/32 divide will always work.
449 */
450 AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL);
451 if (Multiplicand > Quotient)
452 {
453 return (AE_NUMERIC_OVERFLOW);
454 }
455
456 Product = Multiplicand * Base;
457
458 /* Check for 32-bit overflow if necessary */
459
460 if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX))
461 {
462 return (AE_NUMERIC_OVERFLOW);
463 }
464
465 *OutProduct = Product;
466 return (AE_OK);
467 }
468
469
470 /*******************************************************************************
471 *
472 * FUNCTION: AcpiUtStrtoulAdd64
473 *
474 * PARAMETERS: Addend1 - Current accumulated converted integer
475 * Digit - New hex value/char
476 * OutSum - Where sum is returned (Accumulator)
477 *
478 * RETURN: Status and 64-bit sum
479 *
480 * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
481 * well as 32-bit overflow if necessary (if the current global
482 * integer width is 32).
483 *
484 ******************************************************************************/
485
486 static ACPI_STATUS
487 AcpiUtStrtoulAdd64 (
488 UINT64 Addend1,
489 UINT32 Digit,
490 UINT64 *OutSum)
491 {
492 UINT64 Sum;
493
494
495 /* Check for 64-bit overflow before the actual addition */
496
497 if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1)))
498 {
499 return (AE_NUMERIC_OVERFLOW);
500 }
501
502 Sum = Addend1 + Digit;
503
504 /* Check for 32-bit overflow if necessary */
505
506 if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX))
507 {
508 return (AE_NUMERIC_OVERFLOW);
509 }
510
511 *OutSum = Sum;
512 return (AE_OK);
513 }