1285728Sjkim/******************************************************************************* 2285728Sjkim * 3285728Sjkim * Module Name: utnonansi - Non-ansi C library functions 4285728Sjkim * 5285728Sjkim ******************************************************************************/ 6285728Sjkim 7285728Sjkim/* 8298714Sjkim * 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 167298714Sjkim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) 168285728Sjkim/******************************************************************************* 169285728Sjkim * 170298714Sjkim * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat 171298714Sjkim * 172298714Sjkim * PARAMETERS: Adds a "DestSize" parameter to each of the standard string 173298714Sjkim * functions. This is the size of the Destination buffer. 174298714Sjkim * 175298714Sjkim * RETURN: TRUE if the operation would overflow the destination buffer. 176298714Sjkim * 177298714Sjkim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that 178298714Sjkim * the result of the operation will not overflow the output string 179298714Sjkim * buffer. 180298714Sjkim * 181298714Sjkim * NOTE: These functions are typically only helpful for processing 182298714Sjkim * user input and command lines. For most ACPICA code, the 183298714Sjkim * required buffer length is precisely calculated before buffer 184298714Sjkim * allocation, so the use of these functions is unnecessary. 185298714Sjkim * 186298714Sjkim ******************************************************************************/ 187298714Sjkim 188298714SjkimBOOLEAN 189298714SjkimAcpiUtSafeStrcpy ( 190298714Sjkim char *Dest, 191298714Sjkim ACPI_SIZE DestSize, 192298714Sjkim char *Source) 193298714Sjkim{ 194298714Sjkim 195298714Sjkim if (strlen (Source) >= DestSize) 196298714Sjkim { 197298714Sjkim return (TRUE); 198298714Sjkim } 199298714Sjkim 200298714Sjkim strcpy (Dest, Source); 201298714Sjkim return (FALSE); 202298714Sjkim} 203298714Sjkim 204298714SjkimBOOLEAN 205298714SjkimAcpiUtSafeStrcat ( 206298714Sjkim char *Dest, 207298714Sjkim ACPI_SIZE DestSize, 208298714Sjkim char *Source) 209298714Sjkim{ 210298714Sjkim 211298714Sjkim if ((strlen (Dest) + strlen (Source)) >= DestSize) 212298714Sjkim { 213298714Sjkim return (TRUE); 214298714Sjkim } 215298714Sjkim 216298714Sjkim strcat (Dest, Source); 217298714Sjkim return (FALSE); 218298714Sjkim} 219298714Sjkim 220298714SjkimBOOLEAN 221298714SjkimAcpiUtSafeStrncat ( 222298714Sjkim char *Dest, 223298714Sjkim ACPI_SIZE DestSize, 224298714Sjkim char *Source, 225298714Sjkim ACPI_SIZE MaxTransferLength) 226298714Sjkim{ 227298714Sjkim ACPI_SIZE ActualTransferLength; 228298714Sjkim 229298714Sjkim 230298714Sjkim ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source)); 231298714Sjkim 232298714Sjkim if ((strlen (Dest) + ActualTransferLength) >= DestSize) 233298714Sjkim { 234298714Sjkim return (TRUE); 235298714Sjkim } 236298714Sjkim 237298714Sjkim strncat (Dest, Source, MaxTransferLength); 238298714Sjkim return (FALSE); 239298714Sjkim} 240298714Sjkim#endif 241298714Sjkim 242298714Sjkim 243298714Sjkim/******************************************************************************* 244298714Sjkim * 245285728Sjkim * FUNCTION: AcpiUtStrtoul64 246285728Sjkim * 247298714Sjkim * PARAMETERS: String - Null terminated string 248298714Sjkim * Base - Radix of the string: 16 or 10 or 249298714Sjkim * ACPI_ANY_BASE 250298714Sjkim * MaxIntegerByteWidth - Maximum allowable integer,in bytes: 251298714Sjkim * 4 or 8 (32 or 64 bits) 252298714Sjkim * RetInteger - Where the converted integer is 253298714Sjkim * returned 254285728Sjkim * 255285728Sjkim * RETURN: Status and Converted value 256285728Sjkim * 257285728Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a 258298714Sjkim * 32-bit or 64-bit conversion, depending on the input integer 259298714Sjkim * size (often the current mode of the interpreter). 260285728Sjkim * 261298714Sjkim * NOTES: Negative numbers are not supported, as they are not supported 262298714Sjkim * by ACPI. 263285728Sjkim * 264298714Sjkim * AcpiGbl_IntegerByteWidth should be set to the proper width. 265298714Sjkim * For the core ACPICA code, this width depends on the DSDT 266298714Sjkim * version. For iASL, the default byte width is always 8 for the 267298714Sjkim * parser, but error checking is performed later to flag cases 268298714Sjkim * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. 269298714Sjkim * 270298714Sjkim * Does not support Octal strings, not needed at this time. 271298714Sjkim * 272285728Sjkim ******************************************************************************/ 273285728Sjkim 274285728SjkimACPI_STATUS 275285728SjkimAcpiUtStrtoul64 ( 276285728Sjkim char *String, 277285728Sjkim UINT32 Base, 278298714Sjkim 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 290298714Sjkim ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String); 291285728Sjkim 292285728Sjkim 293285728Sjkim switch (Base) 294285728Sjkim { 295285728Sjkim case ACPI_ANY_BASE: 296298714Sjkim 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 320298714Sjkim if (Base == ACPI_ANY_BASE) 321285728Sjkim { 322285728Sjkim /* 323298714Sjkim * 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 { 344298714Sjkim if (Base == ACPI_ANY_BASE) 345285728Sjkim { 346285728Sjkim goto ErrorExit; 347285728Sjkim } 348285728Sjkim else 349285728Sjkim { 350285728Sjkim goto AllDone; 351285728Sjkim } 352285728Sjkim } 353285728Sjkim 354285728Sjkim /* 355298714Sjkim * Perform a 32-bit or 64-bit conversion, depending upon the input 356298714Sjkim * byte width 357285728Sjkim */ 358298714Sjkim Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ? 359298714Sjkim 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 { 394298714Sjkim 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 412298714Sjkim if (SignOf0x && ((ValidDigits > 16) || 413298714Sjkim ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH)))) 414285728Sjkim { 415285728Sjkim /* 416285728Sjkim * This is ToInteger operation case. 417298714Sjkim * 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 425298714Sjkim (void) AcpiUtShortDivide ( 426298714Sjkim (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); 427285728Sjkim 428285728Sjkim if (ReturnValue > Quotient) 429285728Sjkim { 430298714Sjkim 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 458298714Sjkim /* Base was set/validated above (10 or 16) */ 459298714Sjkim 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 471298714Sjkim#ifdef _OBSOLETE_FUNCTIONS 472298714Sjkim/* Removed: 01/2016 */ 473298714Sjkim 474285728Sjkim/******************************************************************************* 475285728Sjkim * 476298714Sjkim * FUNCTION: strtoul64 477285728Sjkim * 478298714Sjkim * PARAMETERS: String - Null terminated string 479298714Sjkim * Terminater - Where a pointer to the terminating byte 480298714Sjkim * is returned 481298714Sjkim * Base - Radix of the string 482285728Sjkim * 483298714Sjkim * RETURN: Converted value 484285728Sjkim * 485298714Sjkim * DESCRIPTION: Convert a string into an unsigned value. 486285728Sjkim * 487285728Sjkim ******************************************************************************/ 488285728Sjkim 489298714SjkimACPI_STATUS 490298714Sjkimstrtoul64 ( 491298714Sjkim char *String, 492298714Sjkim UINT32 Base, 493298714Sjkim UINT64 *RetInteger) 494285728Sjkim{ 495298714Sjkim UINT32 Index; 496298714Sjkim UINT32 Sign; 497298714Sjkim UINT64 ReturnValue = 0; 498298714Sjkim ACPI_STATUS Status = AE_OK; 499285728Sjkim 500298714Sjkim 501298714Sjkim *RetInteger = 0; 502298714Sjkim 503298714Sjkim switch (Base) 504285728Sjkim { 505298714Sjkim case 0: 506298714Sjkim case 8: 507298714Sjkim case 10: 508298714Sjkim case 16: 509298714Sjkim 510298714Sjkim break; 511298714Sjkim 512298714Sjkim default: 513298714Sjkim /* 514298714Sjkim * The specified Base parameter is not in the domain of 515298714Sjkim * this function: 516298714Sjkim */ 517298714Sjkim return (AE_BAD_PARAMETER); 518285728Sjkim } 519285728Sjkim 520298714Sjkim /* Skip over any white space in the buffer: */ 521285728Sjkim 522298714Sjkim while (isspace ((int) *String) || *String == '\t') 523298714Sjkim { 524298714Sjkim ++String; 525298714Sjkim } 526285728Sjkim 527298714Sjkim /* 528298714Sjkim * The buffer may contain an optional plus or minus sign. 529298714Sjkim * If it does, then skip over it but remember what is was: 530298714Sjkim */ 531298714Sjkim if (*String == '-') 532285728Sjkim { 533298714Sjkim Sign = ACPI_SIGN_NEGATIVE; 534298714Sjkim ++String; 535285728Sjkim } 536298714Sjkim else if (*String == '+') 537298714Sjkim { 538298714Sjkim ++String; 539298714Sjkim Sign = ACPI_SIGN_POSITIVE; 540298714Sjkim } 541298714Sjkim else 542298714Sjkim { 543298714Sjkim Sign = ACPI_SIGN_POSITIVE; 544298714Sjkim } 545285728Sjkim 546298714Sjkim /* 547298714Sjkim * If the input parameter Base is zero, then we need to 548298714Sjkim * determine if it is octal, decimal, or hexadecimal: 549298714Sjkim */ 550298714Sjkim if (Base == 0) 551298714Sjkim { 552298714Sjkim if (*String == '0') 553298714Sjkim { 554298714Sjkim if (tolower ((int) *(++String)) == 'x') 555298714Sjkim { 556298714Sjkim Base = 16; 557298714Sjkim ++String; 558298714Sjkim } 559298714Sjkim else 560298714Sjkim { 561298714Sjkim Base = 8; 562298714Sjkim } 563298714Sjkim } 564298714Sjkim else 565298714Sjkim { 566298714Sjkim Base = 10; 567298714Sjkim } 568298714Sjkim } 569298714Sjkim 570298714Sjkim /* 571298714Sjkim * For octal and hexadecimal bases, skip over the leading 572298714Sjkim * 0 or 0x, if they are present. 573298714Sjkim */ 574298714Sjkim if (Base == 8 && *String == '0') 575298714Sjkim { 576298714Sjkim String++; 577298714Sjkim } 578298714Sjkim 579298714Sjkim if (Base == 16 && 580298714Sjkim *String == '0' && 581298714Sjkim tolower ((int) *(++String)) == 'x') 582298714Sjkim { 583298714Sjkim String++; 584298714Sjkim } 585298714Sjkim 586298714Sjkim /* Main loop: convert the string to an unsigned long */ 587298714Sjkim 588298714Sjkim while (*String) 589298714Sjkim { 590298714Sjkim if (isdigit ((int) *String)) 591298714Sjkim { 592298714Sjkim Index = ((UINT8) *String) - '0'; 593298714Sjkim } 594298714Sjkim else 595298714Sjkim { 596298714Sjkim Index = (UINT8) toupper ((int) *String); 597298714Sjkim if (isupper ((int) Index)) 598298714Sjkim { 599298714Sjkim Index = Index - 'A' + 10; 600298714Sjkim } 601298714Sjkim else 602298714Sjkim { 603298714Sjkim goto ErrorExit; 604298714Sjkim } 605298714Sjkim } 606298714Sjkim 607298714Sjkim if (Index >= Base) 608298714Sjkim { 609298714Sjkim goto ErrorExit; 610298714Sjkim } 611298714Sjkim 612298714Sjkim /* Check to see if value is out of range: */ 613298714Sjkim 614298714Sjkim if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 615298714Sjkim (UINT64) Base)) 616298714Sjkim { 617298714Sjkim goto ErrorExit; 618298714Sjkim } 619298714Sjkim else 620298714Sjkim { 621298714Sjkim ReturnValue *= Base; 622298714Sjkim ReturnValue += Index; 623298714Sjkim } 624298714Sjkim 625298714Sjkim ++String; 626298714Sjkim } 627298714Sjkim 628298714Sjkim 629298714Sjkim /* If a minus sign was present, then "the conversion is negated": */ 630298714Sjkim 631298714Sjkim if (Sign == ACPI_SIGN_NEGATIVE) 632298714Sjkim { 633298714Sjkim ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 634298714Sjkim } 635298714Sjkim 636298714Sjkim *RetInteger = ReturnValue; 637298714Sjkim return (Status); 638298714Sjkim 639298714Sjkim 640298714SjkimErrorExit: 641298714Sjkim switch (Base) 642298714Sjkim { 643298714Sjkim case 8: 644298714Sjkim 645298714Sjkim Status = AE_BAD_OCTAL_CONSTANT; 646298714Sjkim break; 647298714Sjkim 648298714Sjkim case 10: 649298714Sjkim 650298714Sjkim Status = AE_BAD_DECIMAL_CONSTANT; 651298714Sjkim break; 652298714Sjkim 653298714Sjkim case 16: 654298714Sjkim 655298714Sjkim Status = AE_BAD_HEX_CONSTANT; 656298714Sjkim break; 657298714Sjkim 658298714Sjkim default: 659298714Sjkim 660298714Sjkim /* Base validated above */ 661298714Sjkim 662298714Sjkim break; 663298714Sjkim } 664298714Sjkim 665298714Sjkim return (Status); 666285728Sjkim} 667285728Sjkim#endif 668