1285728Sjkim/******************************************************************************* 2285728Sjkim * 3285728Sjkim * Module Name: utnonansi - Non-ansi C library functions 4285728Sjkim * 5285728Sjkim ******************************************************************************/ 6285728Sjkim 7285728Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9285728Sjkim * All rights reserved. 10285728Sjkim * 11285728Sjkim * Redistribution and use in source and binary forms, with or without 12285728Sjkim * modification, are permitted provided that the following conditions 13285728Sjkim * are met: 14285728Sjkim * 1. Redistributions of source code must retain the above copyright 15285728Sjkim * notice, this list of conditions, and the following disclaimer, 16285728Sjkim * without modification. 17285728Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18285728Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19285728Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20285728Sjkim * including a substantially similar Disclaimer requirement for further 21285728Sjkim * binary redistribution. 22285728Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23285728Sjkim * of any contributors may be used to endorse or promote products derived 24285728Sjkim * from this software without specific prior written permission. 25285728Sjkim * 26285728Sjkim * Alternatively, this software may be distributed under the terms of the 27285728Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28285728Sjkim * Software Foundation. 29285728Sjkim * 30285728Sjkim * NO WARRANTY 31285728Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32285728Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33285728Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34285728Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35285728Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36285728Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37285728Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38285728Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39285728Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40285728Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41285728Sjkim * POSSIBILITY OF SUCH DAMAGES. 42285728Sjkim */ 43285728Sjkim 44285797Sjkim#include <contrib/dev/acpica/include/acpi.h> 45285797Sjkim#include <contrib/dev/acpica/include/accommon.h> 46285728Sjkim 47285728Sjkim 48285728Sjkim#define _COMPONENT ACPI_UTILITIES 49285728Sjkim ACPI_MODULE_NAME ("utnonansi") 50285728Sjkim 51285728Sjkim 52285728Sjkim/* 53285728Sjkim * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit 54285728Sjkim * version of strtoul. 55285728Sjkim */ 56285728Sjkim 57285728Sjkim/******************************************************************************* 58285728Sjkim * 59285728Sjkim * FUNCTION: AcpiUtStrlwr (strlwr) 60285728Sjkim * 61285728Sjkim * PARAMETERS: SrcString - The source string to convert 62285728Sjkim * 63285728Sjkim * RETURN: None 64285728Sjkim * 65285728Sjkim * DESCRIPTION: Convert a string to lowercase 66285728Sjkim * 67285728Sjkim ******************************************************************************/ 68285728Sjkim 69285728Sjkimvoid 70285728SjkimAcpiUtStrlwr ( 71285728Sjkim char *SrcString) 72285728Sjkim{ 73285728Sjkim char *String; 74285728Sjkim 75285728Sjkim 76285728Sjkim ACPI_FUNCTION_ENTRY (); 77285728Sjkim 78285728Sjkim 79285728Sjkim if (!SrcString) 80285728Sjkim { 81285728Sjkim return; 82285728Sjkim } 83285728Sjkim 84285728Sjkim /* Walk entire string, lowercasing the letters */ 85285728Sjkim 86285728Sjkim for (String = SrcString; *String; String++) 87285728Sjkim { 88285728Sjkim *String = (char) tolower ((int) *String); 89285728Sjkim } 90285728Sjkim} 91285728Sjkim 92285728Sjkim 93285728Sjkim/******************************************************************************* 94285728Sjkim * 95285728Sjkim * FUNCTION: AcpiUtStrupr (strupr) 96285728Sjkim * 97285728Sjkim * PARAMETERS: SrcString - The source string to convert 98285728Sjkim * 99285728Sjkim * RETURN: None 100285728Sjkim * 101285728Sjkim * DESCRIPTION: Convert a string to uppercase 102285728Sjkim * 103285728Sjkim ******************************************************************************/ 104285728Sjkim 105285728Sjkimvoid 106285728SjkimAcpiUtStrupr ( 107285728Sjkim char *SrcString) 108285728Sjkim{ 109285728Sjkim char *String; 110285728Sjkim 111285728Sjkim 112285728Sjkim ACPI_FUNCTION_ENTRY (); 113285728Sjkim 114285728Sjkim 115285728Sjkim if (!SrcString) 116285728Sjkim { 117285728Sjkim return; 118285728Sjkim } 119285728Sjkim 120285728Sjkim /* Walk entire string, uppercasing the letters */ 121285728Sjkim 122285728Sjkim for (String = SrcString; *String; String++) 123285728Sjkim { 124285728Sjkim *String = (char) toupper ((int) *String); 125285728Sjkim } 126285728Sjkim} 127285728Sjkim 128285728Sjkim 129285728Sjkim/****************************************************************************** 130285728Sjkim * 131285728Sjkim * FUNCTION: AcpiUtStricmp (stricmp) 132285728Sjkim * 133285728Sjkim * PARAMETERS: String1 - first string to compare 134285728Sjkim * String2 - second string to compare 135285728Sjkim * 136285728Sjkim * RETURN: int that signifies string relationship. Zero means strings 137285728Sjkim * are equal. 138285728Sjkim * 139285728Sjkim * DESCRIPTION: Case-insensitive string compare. Implementation of the 140285728Sjkim * non-ANSI stricmp function. 141285728Sjkim * 142285728Sjkim ******************************************************************************/ 143285728Sjkim 144285728Sjkimint 145285728SjkimAcpiUtStricmp ( 146285728Sjkim char *String1, 147285728Sjkim char *String2) 148285728Sjkim{ 149285728Sjkim int c1; 150285728Sjkim int c2; 151285728Sjkim 152285728Sjkim 153285728Sjkim do 154285728Sjkim { 155285728Sjkim c1 = tolower ((int) *String1); 156285728Sjkim c2 = tolower ((int) *String2); 157285728Sjkim 158285728Sjkim String1++; 159285728Sjkim String2++; 160285728Sjkim } 161285728Sjkim while ((c1 == c2) && (c1)); 162285728Sjkim 163285728Sjkim return (c1 - c2); 164285728Sjkim} 165285728Sjkim 166285728Sjkim 167306536Sjkim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) 168285728Sjkim/******************************************************************************* 169285728Sjkim * 170306536Sjkim * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat 171306536Sjkim * 172306536Sjkim * PARAMETERS: Adds a "DestSize" parameter to each of the standard string 173306536Sjkim * functions. This is the size of the Destination buffer. 174306536Sjkim * 175306536Sjkim * RETURN: TRUE if the operation would overflow the destination buffer. 176306536Sjkim * 177306536Sjkim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that 178306536Sjkim * the result of the operation will not overflow the output string 179306536Sjkim * buffer. 180306536Sjkim * 181306536Sjkim * NOTE: These functions are typically only helpful for processing 182306536Sjkim * user input and command lines. For most ACPICA code, the 183306536Sjkim * required buffer length is precisely calculated before buffer 184306536Sjkim * allocation, so the use of these functions is unnecessary. 185306536Sjkim * 186306536Sjkim ******************************************************************************/ 187306536Sjkim 188306536SjkimBOOLEAN 189306536SjkimAcpiUtSafeStrcpy ( 190306536Sjkim char *Dest, 191306536Sjkim ACPI_SIZE DestSize, 192306536Sjkim char *Source) 193306536Sjkim{ 194306536Sjkim 195306536Sjkim if (strlen (Source) >= DestSize) 196306536Sjkim { 197306536Sjkim return (TRUE); 198306536Sjkim } 199306536Sjkim 200306536Sjkim strcpy (Dest, Source); 201306536Sjkim return (FALSE); 202306536Sjkim} 203306536Sjkim 204306536SjkimBOOLEAN 205306536SjkimAcpiUtSafeStrcat ( 206306536Sjkim char *Dest, 207306536Sjkim ACPI_SIZE DestSize, 208306536Sjkim char *Source) 209306536Sjkim{ 210306536Sjkim 211306536Sjkim if ((strlen (Dest) + strlen (Source)) >= DestSize) 212306536Sjkim { 213306536Sjkim return (TRUE); 214306536Sjkim } 215306536Sjkim 216306536Sjkim strcat (Dest, Source); 217306536Sjkim return (FALSE); 218306536Sjkim} 219306536Sjkim 220306536SjkimBOOLEAN 221306536SjkimAcpiUtSafeStrncat ( 222306536Sjkim char *Dest, 223306536Sjkim ACPI_SIZE DestSize, 224306536Sjkim char *Source, 225306536Sjkim ACPI_SIZE MaxTransferLength) 226306536Sjkim{ 227306536Sjkim ACPI_SIZE ActualTransferLength; 228306536Sjkim 229306536Sjkim 230306536Sjkim ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source)); 231306536Sjkim 232306536Sjkim if ((strlen (Dest) + ActualTransferLength) >= DestSize) 233306536Sjkim { 234306536Sjkim return (TRUE); 235306536Sjkim } 236306536Sjkim 237306536Sjkim strncat (Dest, Source, MaxTransferLength); 238306536Sjkim return (FALSE); 239306536Sjkim} 240306536Sjkim#endif 241306536Sjkim 242306536Sjkim 243306536Sjkim/******************************************************************************* 244306536Sjkim * 245285728Sjkim * FUNCTION: AcpiUtStrtoul64 246285728Sjkim * 247306536Sjkim * PARAMETERS: String - Null terminated string 248306536Sjkim * Base - Radix of the string: 16 or 10 or 249306536Sjkim * ACPI_ANY_BASE 250306536Sjkim * MaxIntegerByteWidth - Maximum allowable integer,in bytes: 251306536Sjkim * 4 or 8 (32 or 64 bits) 252306536Sjkim * RetInteger - Where the converted integer is 253306536Sjkim * returned 254285728Sjkim * 255285728Sjkim * RETURN: Status and Converted value 256285728Sjkim * 257285728Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a 258306536Sjkim * 32-bit or 64-bit conversion, depending on the input integer 259306536Sjkim * size (often the current mode of the interpreter). 260285728Sjkim * 261306536Sjkim * NOTES: Negative numbers are not supported, as they are not supported 262306536Sjkim * by ACPI. 263285728Sjkim * 264306536Sjkim * AcpiGbl_IntegerByteWidth should be set to the proper width. 265306536Sjkim * For the core ACPICA code, this width depends on the DSDT 266306536Sjkim * version. For iASL, the default byte width is always 8 for the 267306536Sjkim * parser, but error checking is performed later to flag cases 268306536Sjkim * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. 269306536Sjkim * 270306536Sjkim * Does not support Octal strings, not needed at this time. 271306536Sjkim * 272285728Sjkim ******************************************************************************/ 273285728Sjkim 274285728SjkimACPI_STATUS 275285728SjkimAcpiUtStrtoul64 ( 276285728Sjkim char *String, 277285728Sjkim UINT32 Base, 278306536Sjkim UINT32 MaxIntegerByteWidth, 279285728Sjkim UINT64 *RetInteger) 280285728Sjkim{ 281285728Sjkim UINT32 ThisDigit = 0; 282285728Sjkim UINT64 ReturnValue = 0; 283285728Sjkim UINT64 Quotient; 284285728Sjkim UINT64 Dividend; 285285728Sjkim UINT8 ValidDigits = 0; 286285728Sjkim UINT8 SignOf0x = 0; 287285728Sjkim UINT8 Term = 0; 288285728Sjkim 289285728Sjkim 290306536Sjkim ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String); 291285728Sjkim 292285728Sjkim 293285728Sjkim switch (Base) 294285728Sjkim { 295285728Sjkim case ACPI_ANY_BASE: 296306536Sjkim case 10: 297285728Sjkim case 16: 298285728Sjkim 299285728Sjkim break; 300285728Sjkim 301285728Sjkim default: 302285728Sjkim 303285728Sjkim /* Invalid Base */ 304285728Sjkim 305285728Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 306285728Sjkim } 307285728Sjkim 308285728Sjkim if (!String) 309285728Sjkim { 310285728Sjkim goto ErrorExit; 311285728Sjkim } 312285728Sjkim 313285728Sjkim /* Skip over any white space in the buffer */ 314285728Sjkim 315285728Sjkim while ((*String) && (isspace ((int) *String) || *String == '\t')) 316285728Sjkim { 317285728Sjkim String++; 318285728Sjkim } 319285728Sjkim 320306536Sjkim if (Base == ACPI_ANY_BASE) 321285728Sjkim { 322285728Sjkim /* 323306536Sjkim * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'. 324285728Sjkim * We need to determine if it is decimal or hexadecimal. 325285728Sjkim */ 326285728Sjkim if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x')) 327285728Sjkim { 328285728Sjkim SignOf0x = 1; 329285728Sjkim Base = 16; 330285728Sjkim 331285728Sjkim /* Skip over the leading '0x' */ 332285728Sjkim String += 2; 333285728Sjkim } 334285728Sjkim else 335285728Sjkim { 336285728Sjkim Base = 10; 337285728Sjkim } 338285728Sjkim } 339285728Sjkim 340285728Sjkim /* Any string left? Check that '0x' is not followed by white space. */ 341285728Sjkim 342285728Sjkim if (!(*String) || isspace ((int) *String) || *String == '\t') 343285728Sjkim { 344306536Sjkim if (Base == ACPI_ANY_BASE) 345285728Sjkim { 346285728Sjkim goto ErrorExit; 347285728Sjkim } 348285728Sjkim else 349285728Sjkim { 350285728Sjkim goto AllDone; 351285728Sjkim } 352285728Sjkim } 353285728Sjkim 354285728Sjkim /* 355306536Sjkim * Perform a 32-bit or 64-bit conversion, depending upon the input 356306536Sjkim * byte width 357285728Sjkim */ 358306536Sjkim Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ? 359306536Sjkim ACPI_UINT32_MAX : ACPI_UINT64_MAX; 360285728Sjkim 361285728Sjkim /* Main loop: convert the string to a 32- or 64-bit integer */ 362285728Sjkim 363285728Sjkim while (*String) 364285728Sjkim { 365285728Sjkim if (isdigit ((int) *String)) 366285728Sjkim { 367285728Sjkim /* Convert ASCII 0-9 to Decimal value */ 368285728Sjkim 369285728Sjkim ThisDigit = ((UINT8) *String) - '0'; 370285728Sjkim } 371285728Sjkim else if (Base == 10) 372285728Sjkim { 373285728Sjkim /* Digit is out of range; possible in ToInteger case only */ 374285728Sjkim 375285728Sjkim Term = 1; 376285728Sjkim } 377285728Sjkim else 378285728Sjkim { 379285728Sjkim ThisDigit = (UINT8) toupper ((int) *String); 380285728Sjkim if (isxdigit ((int) ThisDigit)) 381285728Sjkim { 382285728Sjkim /* Convert ASCII Hex char to value */ 383285728Sjkim 384285728Sjkim ThisDigit = ThisDigit - 'A' + 10; 385285728Sjkim } 386285728Sjkim else 387285728Sjkim { 388285728Sjkim Term = 1; 389285728Sjkim } 390285728Sjkim } 391285728Sjkim 392285728Sjkim if (Term) 393285728Sjkim { 394306536Sjkim if (Base == ACPI_ANY_BASE) 395285728Sjkim { 396285728Sjkim goto ErrorExit; 397285728Sjkim } 398285728Sjkim else 399285728Sjkim { 400285728Sjkim break; 401285728Sjkim } 402285728Sjkim } 403285728Sjkim else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 404285728Sjkim { 405285728Sjkim /* Skip zeros */ 406285728Sjkim String++; 407285728Sjkim continue; 408285728Sjkim } 409285728Sjkim 410285728Sjkim ValidDigits++; 411285728Sjkim 412306536Sjkim if (SignOf0x && ((ValidDigits > 16) || 413306536Sjkim ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH)))) 414285728Sjkim { 415285728Sjkim /* 416285728Sjkim * This is ToInteger operation case. 417306536Sjkim * No restrictions for string-to-integer conversion, 418285728Sjkim * see ACPI spec. 419285728Sjkim */ 420285728Sjkim goto ErrorExit; 421285728Sjkim } 422285728Sjkim 423285728Sjkim /* Divide the digit into the correct position */ 424285728Sjkim 425306536Sjkim (void) AcpiUtShortDivide ( 426306536Sjkim (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); 427285728Sjkim 428285728Sjkim if (ReturnValue > Quotient) 429285728Sjkim { 430306536Sjkim if (Base == ACPI_ANY_BASE) 431285728Sjkim { 432285728Sjkim goto ErrorExit; 433285728Sjkim } 434285728Sjkim else 435285728Sjkim { 436285728Sjkim break; 437285728Sjkim } 438285728Sjkim } 439285728Sjkim 440285728Sjkim ReturnValue *= Base; 441285728Sjkim ReturnValue += ThisDigit; 442285728Sjkim String++; 443285728Sjkim } 444285728Sjkim 445285728Sjkim /* All done, normal exit */ 446285728Sjkim 447285728SjkimAllDone: 448285728Sjkim 449285728Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 450285728Sjkim ACPI_FORMAT_UINT64 (ReturnValue))); 451285728Sjkim 452285728Sjkim *RetInteger = ReturnValue; 453285728Sjkim return_ACPI_STATUS (AE_OK); 454285728Sjkim 455285728Sjkim 456285728SjkimErrorExit: 457285728Sjkim 458306536Sjkim /* Base was set/validated above (10 or 16) */ 459306536Sjkim 460285728Sjkim if (Base == 10) 461285728Sjkim { 462285728Sjkim return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 463285728Sjkim } 464285728Sjkim else 465285728Sjkim { 466285728Sjkim return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 467285728Sjkim } 468285728Sjkim} 469285728Sjkim 470285728Sjkim 471306536Sjkim#ifdef _OBSOLETE_FUNCTIONS 472306536Sjkim/* Removed: 01/2016 */ 473306536Sjkim 474285728Sjkim/******************************************************************************* 475285728Sjkim * 476306536Sjkim * FUNCTION: strtoul64 477285728Sjkim * 478306536Sjkim * PARAMETERS: String - Null terminated string 479306536Sjkim * Terminater - Where a pointer to the terminating byte 480306536Sjkim * is returned 481306536Sjkim * Base - Radix of the string 482285728Sjkim * 483306536Sjkim * RETURN: Converted value 484285728Sjkim * 485306536Sjkim * DESCRIPTION: Convert a string into an unsigned value. 486285728Sjkim * 487285728Sjkim ******************************************************************************/ 488285728Sjkim 489306536SjkimACPI_STATUS 490306536Sjkimstrtoul64 ( 491306536Sjkim char *String, 492306536Sjkim UINT32 Base, 493306536Sjkim UINT64 *RetInteger) 494285728Sjkim{ 495306536Sjkim UINT32 Index; 496306536Sjkim UINT32 Sign; 497306536Sjkim UINT64 ReturnValue = 0; 498306536Sjkim ACPI_STATUS Status = AE_OK; 499285728Sjkim 500306536Sjkim 501306536Sjkim *RetInteger = 0; 502306536Sjkim 503306536Sjkim switch (Base) 504285728Sjkim { 505306536Sjkim case 0: 506306536Sjkim case 8: 507306536Sjkim case 10: 508306536Sjkim case 16: 509306536Sjkim 510306536Sjkim break; 511306536Sjkim 512306536Sjkim default: 513306536Sjkim /* 514306536Sjkim * The specified Base parameter is not in the domain of 515306536Sjkim * this function: 516306536Sjkim */ 517306536Sjkim return (AE_BAD_PARAMETER); 518285728Sjkim } 519285728Sjkim 520306536Sjkim /* Skip over any white space in the buffer: */ 521285728Sjkim 522306536Sjkim while (isspace ((int) *String) || *String == '\t') 523306536Sjkim { 524306536Sjkim ++String; 525306536Sjkim } 526285728Sjkim 527306536Sjkim /* 528306536Sjkim * The buffer may contain an optional plus or minus sign. 529306536Sjkim * If it does, then skip over it but remember what is was: 530306536Sjkim */ 531306536Sjkim if (*String == '-') 532285728Sjkim { 533306536Sjkim Sign = ACPI_SIGN_NEGATIVE; 534306536Sjkim ++String; 535285728Sjkim } 536306536Sjkim else if (*String == '+') 537306536Sjkim { 538306536Sjkim ++String; 539306536Sjkim Sign = ACPI_SIGN_POSITIVE; 540306536Sjkim } 541306536Sjkim else 542306536Sjkim { 543306536Sjkim Sign = ACPI_SIGN_POSITIVE; 544306536Sjkim } 545285728Sjkim 546306536Sjkim /* 547306536Sjkim * If the input parameter Base is zero, then we need to 548306536Sjkim * determine if it is octal, decimal, or hexadecimal: 549306536Sjkim */ 550306536Sjkim if (Base == 0) 551306536Sjkim { 552306536Sjkim if (*String == '0') 553306536Sjkim { 554306536Sjkim if (tolower ((int) *(++String)) == 'x') 555306536Sjkim { 556306536Sjkim Base = 16; 557306536Sjkim ++String; 558306536Sjkim } 559306536Sjkim else 560306536Sjkim { 561306536Sjkim Base = 8; 562306536Sjkim } 563306536Sjkim } 564306536Sjkim else 565306536Sjkim { 566306536Sjkim Base = 10; 567306536Sjkim } 568306536Sjkim } 569285728Sjkim 570306536Sjkim /* 571306536Sjkim * For octal and hexadecimal bases, skip over the leading 572306536Sjkim * 0 or 0x, if they are present. 573306536Sjkim */ 574306536Sjkim if (Base == 8 && *String == '0') 575306536Sjkim { 576306536Sjkim String++; 577306536Sjkim } 578285728Sjkim 579306536Sjkim if (Base == 16 && 580306536Sjkim *String == '0' && 581306536Sjkim tolower ((int) *(++String)) == 'x') 582306536Sjkim { 583306536Sjkim String++; 584306536Sjkim } 585285728Sjkim 586306536Sjkim /* Main loop: convert the string to an unsigned long */ 587285728Sjkim 588306536Sjkim while (*String) 589285728Sjkim { 590306536Sjkim if (isdigit ((int) *String)) 591306536Sjkim { 592306536Sjkim Index = ((UINT8) *String) - '0'; 593306536Sjkim } 594306536Sjkim else 595306536Sjkim { 596306536Sjkim Index = (UINT8) toupper ((int) *String); 597306536Sjkim if (isupper ((int) Index)) 598306536Sjkim { 599306536Sjkim Index = Index - 'A' + 10; 600306536Sjkim } 601306536Sjkim else 602306536Sjkim { 603306536Sjkim goto ErrorExit; 604306536Sjkim } 605306536Sjkim } 606306536Sjkim 607306536Sjkim if (Index >= Base) 608306536Sjkim { 609306536Sjkim goto ErrorExit; 610306536Sjkim } 611306536Sjkim 612306536Sjkim /* Check to see if value is out of range: */ 613306536Sjkim 614306536Sjkim if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 615306536Sjkim (UINT64) Base)) 616306536Sjkim { 617306536Sjkim goto ErrorExit; 618306536Sjkim } 619306536Sjkim else 620306536Sjkim { 621306536Sjkim ReturnValue *= Base; 622306536Sjkim ReturnValue += Index; 623306536Sjkim } 624306536Sjkim 625306536Sjkim ++String; 626285728Sjkim } 627285728Sjkim 628306536Sjkim 629306536Sjkim /* If a minus sign was present, then "the conversion is negated": */ 630306536Sjkim 631306536Sjkim if (Sign == ACPI_SIGN_NEGATIVE) 632306536Sjkim { 633306536Sjkim ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 634306536Sjkim } 635306536Sjkim 636306536Sjkim *RetInteger = ReturnValue; 637306536Sjkim return (Status); 638306536Sjkim 639306536Sjkim 640306536SjkimErrorExit: 641306536Sjkim switch (Base) 642306536Sjkim { 643306536Sjkim case 8: 644306536Sjkim 645306536Sjkim Status = AE_BAD_OCTAL_CONSTANT; 646306536Sjkim break; 647306536Sjkim 648306536Sjkim case 10: 649306536Sjkim 650306536Sjkim Status = AE_BAD_DECIMAL_CONSTANT; 651306536Sjkim break; 652306536Sjkim 653306536Sjkim case 16: 654306536Sjkim 655306536Sjkim Status = AE_BAD_HEX_CONSTANT; 656306536Sjkim break; 657306536Sjkim 658306536Sjkim default: 659306536Sjkim 660306536Sjkim /* Base validated above */ 661306536Sjkim 662306536Sjkim break; 663306536Sjkim } 664306536Sjkim 665306536Sjkim return (Status); 666285728Sjkim} 667285728Sjkim#endif 668