1*bc36eafdSMike Gerdts /******************************************************************************* 2*bc36eafdSMike Gerdts * 3*bc36eafdSMike Gerdts * Module Name: utnonansi - Non-ansi C library functions 4*bc36eafdSMike Gerdts * 5*bc36eafdSMike Gerdts ******************************************************************************/ 6*bc36eafdSMike Gerdts 7*bc36eafdSMike Gerdts /* 8*bc36eafdSMike Gerdts * Copyright (C) 2000 - 2016, Intel Corp. 9*bc36eafdSMike Gerdts * All rights reserved. 10*bc36eafdSMike Gerdts * 11*bc36eafdSMike Gerdts * Redistribution and use in source and binary forms, with or without 12*bc36eafdSMike Gerdts * modification, are permitted provided that the following conditions 13*bc36eafdSMike Gerdts * are met: 14*bc36eafdSMike Gerdts * 1. Redistributions of source code must retain the above copyright 15*bc36eafdSMike Gerdts * notice, this list of conditions, and the following disclaimer, 16*bc36eafdSMike Gerdts * without modification. 17*bc36eafdSMike Gerdts * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*bc36eafdSMike Gerdts * substantially similar to the "NO WARRANTY" disclaimer below 19*bc36eafdSMike Gerdts * ("Disclaimer") and any redistribution must be conditioned upon 20*bc36eafdSMike Gerdts * including a substantially similar Disclaimer requirement for further 21*bc36eafdSMike Gerdts * binary redistribution. 22*bc36eafdSMike Gerdts * 3. Neither the names of the above-listed copyright holders nor the names 23*bc36eafdSMike Gerdts * of any contributors may be used to endorse or promote products derived 24*bc36eafdSMike Gerdts * from this software without specific prior written permission. 25*bc36eafdSMike Gerdts * 26*bc36eafdSMike Gerdts * Alternatively, this software may be distributed under the terms of the 27*bc36eafdSMike Gerdts * GNU General Public License ("GPL") version 2 as published by the Free 28*bc36eafdSMike Gerdts * Software Foundation. 29*bc36eafdSMike Gerdts * 30*bc36eafdSMike Gerdts * NO WARRANTY 31*bc36eafdSMike Gerdts * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*bc36eafdSMike Gerdts * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*bc36eafdSMike Gerdts * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*bc36eafdSMike Gerdts * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*bc36eafdSMike Gerdts * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*bc36eafdSMike Gerdts * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*bc36eafdSMike Gerdts * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*bc36eafdSMike Gerdts * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*bc36eafdSMike Gerdts * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*bc36eafdSMike Gerdts * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*bc36eafdSMike Gerdts * POSSIBILITY OF SUCH DAMAGES. 42*bc36eafdSMike Gerdts */ 43*bc36eafdSMike Gerdts 44*bc36eafdSMike Gerdts #include "acpi.h" 45*bc36eafdSMike Gerdts #include "accommon.h" 46*bc36eafdSMike Gerdts 47*bc36eafdSMike Gerdts 48*bc36eafdSMike Gerdts #define _COMPONENT ACPI_UTILITIES 49*bc36eafdSMike Gerdts ACPI_MODULE_NAME ("utnonansi") 50*bc36eafdSMike Gerdts 51*bc36eafdSMike Gerdts 52*bc36eafdSMike Gerdts /* 53*bc36eafdSMike Gerdts * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit 54*bc36eafdSMike Gerdts * version of strtoul. 55*bc36eafdSMike Gerdts */ 56*bc36eafdSMike Gerdts 57*bc36eafdSMike Gerdts /******************************************************************************* 58*bc36eafdSMike Gerdts * 59*bc36eafdSMike Gerdts * FUNCTION: AcpiUtStrlwr (strlwr) 60*bc36eafdSMike Gerdts * 61*bc36eafdSMike Gerdts * PARAMETERS: SrcString - The source string to convert 62*bc36eafdSMike Gerdts * 63*bc36eafdSMike Gerdts * RETURN: None 64*bc36eafdSMike Gerdts * 65*bc36eafdSMike Gerdts * DESCRIPTION: Convert a string to lowercase 66*bc36eafdSMike Gerdts * 67*bc36eafdSMike Gerdts ******************************************************************************/ 68*bc36eafdSMike Gerdts 69*bc36eafdSMike Gerdts void 70*bc36eafdSMike Gerdts AcpiUtStrlwr ( 71*bc36eafdSMike Gerdts char *SrcString) 72*bc36eafdSMike Gerdts { 73*bc36eafdSMike Gerdts char *String; 74*bc36eafdSMike Gerdts 75*bc36eafdSMike Gerdts 76*bc36eafdSMike Gerdts ACPI_FUNCTION_ENTRY (); 77*bc36eafdSMike Gerdts 78*bc36eafdSMike Gerdts 79*bc36eafdSMike Gerdts if (!SrcString) 80*bc36eafdSMike Gerdts { 81*bc36eafdSMike Gerdts return; 82*bc36eafdSMike Gerdts } 83*bc36eafdSMike Gerdts 84*bc36eafdSMike Gerdts /* Walk entire string, lowercasing the letters */ 85*bc36eafdSMike Gerdts 86*bc36eafdSMike Gerdts for (String = SrcString; *String; String++) 87*bc36eafdSMike Gerdts { 88*bc36eafdSMike Gerdts *String = (char) tolower ((int) *String); 89*bc36eafdSMike Gerdts } 90*bc36eafdSMike Gerdts } 91*bc36eafdSMike Gerdts 92*bc36eafdSMike Gerdts 93*bc36eafdSMike Gerdts /******************************************************************************* 94*bc36eafdSMike Gerdts * 95*bc36eafdSMike Gerdts * FUNCTION: AcpiUtStrupr (strupr) 96*bc36eafdSMike Gerdts * 97*bc36eafdSMike Gerdts * PARAMETERS: SrcString - The source string to convert 98*bc36eafdSMike Gerdts * 99*bc36eafdSMike Gerdts * RETURN: None 100*bc36eafdSMike Gerdts * 101*bc36eafdSMike Gerdts * DESCRIPTION: Convert a string to uppercase 102*bc36eafdSMike Gerdts * 103*bc36eafdSMike Gerdts ******************************************************************************/ 104*bc36eafdSMike Gerdts 105*bc36eafdSMike Gerdts void 106*bc36eafdSMike Gerdts AcpiUtStrupr ( 107*bc36eafdSMike Gerdts char *SrcString) 108*bc36eafdSMike Gerdts { 109*bc36eafdSMike Gerdts char *String; 110*bc36eafdSMike Gerdts 111*bc36eafdSMike Gerdts 112*bc36eafdSMike Gerdts ACPI_FUNCTION_ENTRY (); 113*bc36eafdSMike Gerdts 114*bc36eafdSMike Gerdts 115*bc36eafdSMike Gerdts if (!SrcString) 116*bc36eafdSMike Gerdts { 117*bc36eafdSMike Gerdts return; 118*bc36eafdSMike Gerdts } 119*bc36eafdSMike Gerdts 120*bc36eafdSMike Gerdts /* Walk entire string, uppercasing the letters */ 121*bc36eafdSMike Gerdts 122*bc36eafdSMike Gerdts for (String = SrcString; *String; String++) 123*bc36eafdSMike Gerdts { 124*bc36eafdSMike Gerdts *String = (char) toupper ((int) *String); 125*bc36eafdSMike Gerdts } 126*bc36eafdSMike Gerdts } 127*bc36eafdSMike Gerdts 128*bc36eafdSMike Gerdts 129*bc36eafdSMike Gerdts /****************************************************************************** 130*bc36eafdSMike Gerdts * 131*bc36eafdSMike Gerdts * FUNCTION: AcpiUtStricmp (stricmp) 132*bc36eafdSMike Gerdts * 133*bc36eafdSMike Gerdts * PARAMETERS: String1 - first string to compare 134*bc36eafdSMike Gerdts * String2 - second string to compare 135*bc36eafdSMike Gerdts * 136*bc36eafdSMike Gerdts * RETURN: int that signifies string relationship. Zero means strings 137*bc36eafdSMike Gerdts * are equal. 138*bc36eafdSMike Gerdts * 139*bc36eafdSMike Gerdts * DESCRIPTION: Case-insensitive string compare. Implementation of the 140*bc36eafdSMike Gerdts * non-ANSI stricmp function. 141*bc36eafdSMike Gerdts * 142*bc36eafdSMike Gerdts ******************************************************************************/ 143*bc36eafdSMike Gerdts 144*bc36eafdSMike Gerdts int 145*bc36eafdSMike Gerdts AcpiUtStricmp ( 146*bc36eafdSMike Gerdts char *String1, 147*bc36eafdSMike Gerdts char *String2) 148*bc36eafdSMike Gerdts { 149*bc36eafdSMike Gerdts int c1; 150*bc36eafdSMike Gerdts int c2; 151*bc36eafdSMike Gerdts 152*bc36eafdSMike Gerdts 153*bc36eafdSMike Gerdts do 154*bc36eafdSMike Gerdts { 155*bc36eafdSMike Gerdts c1 = tolower ((int) *String1); 156*bc36eafdSMike Gerdts c2 = tolower ((int) *String2); 157*bc36eafdSMike Gerdts 158*bc36eafdSMike Gerdts String1++; 159*bc36eafdSMike Gerdts String2++; 160*bc36eafdSMike Gerdts } 161*bc36eafdSMike Gerdts while ((c1 == c2) && (c1)); 162*bc36eafdSMike Gerdts 163*bc36eafdSMike Gerdts return (c1 - c2); 164*bc36eafdSMike Gerdts } 165*bc36eafdSMike Gerdts 166*bc36eafdSMike Gerdts 167*bc36eafdSMike Gerdts #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) 168*bc36eafdSMike Gerdts /******************************************************************************* 169*bc36eafdSMike Gerdts * 170*bc36eafdSMike Gerdts * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat 171*bc36eafdSMike Gerdts * 172*bc36eafdSMike Gerdts * PARAMETERS: Adds a "DestSize" parameter to each of the standard string 173*bc36eafdSMike Gerdts * functions. This is the size of the Destination buffer. 174*bc36eafdSMike Gerdts * 175*bc36eafdSMike Gerdts * RETURN: TRUE if the operation would overflow the destination buffer. 176*bc36eafdSMike Gerdts * 177*bc36eafdSMike Gerdts * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that 178*bc36eafdSMike Gerdts * the result of the operation will not overflow the output string 179*bc36eafdSMike Gerdts * buffer. 180*bc36eafdSMike Gerdts * 181*bc36eafdSMike Gerdts * NOTE: These functions are typically only helpful for processing 182*bc36eafdSMike Gerdts * user input and command lines. For most ACPICA code, the 183*bc36eafdSMike Gerdts * required buffer length is precisely calculated before buffer 184*bc36eafdSMike Gerdts * allocation, so the use of these functions is unnecessary. 185*bc36eafdSMike Gerdts * 186*bc36eafdSMike Gerdts ******************************************************************************/ 187*bc36eafdSMike Gerdts 188*bc36eafdSMike Gerdts BOOLEAN 189*bc36eafdSMike Gerdts AcpiUtSafeStrcpy ( 190*bc36eafdSMike Gerdts char *Dest, 191*bc36eafdSMike Gerdts ACPI_SIZE DestSize, 192*bc36eafdSMike Gerdts char *Source) 193*bc36eafdSMike Gerdts { 194*bc36eafdSMike Gerdts 195*bc36eafdSMike Gerdts if (strlen (Source) >= DestSize) 196*bc36eafdSMike Gerdts { 197*bc36eafdSMike Gerdts return (TRUE); 198*bc36eafdSMike Gerdts } 199*bc36eafdSMike Gerdts 200*bc36eafdSMike Gerdts strcpy (Dest, Source); 201*bc36eafdSMike Gerdts return (FALSE); 202*bc36eafdSMike Gerdts } 203*bc36eafdSMike Gerdts 204*bc36eafdSMike Gerdts BOOLEAN 205*bc36eafdSMike Gerdts AcpiUtSafeStrcat ( 206*bc36eafdSMike Gerdts char *Dest, 207*bc36eafdSMike Gerdts ACPI_SIZE DestSize, 208*bc36eafdSMike Gerdts char *Source) 209*bc36eafdSMike Gerdts { 210*bc36eafdSMike Gerdts 211*bc36eafdSMike Gerdts if ((strlen (Dest) + strlen (Source)) >= DestSize) 212*bc36eafdSMike Gerdts { 213*bc36eafdSMike Gerdts return (TRUE); 214*bc36eafdSMike Gerdts } 215*bc36eafdSMike Gerdts 216*bc36eafdSMike Gerdts strcat (Dest, Source); 217*bc36eafdSMike Gerdts return (FALSE); 218*bc36eafdSMike Gerdts } 219*bc36eafdSMike Gerdts 220*bc36eafdSMike Gerdts BOOLEAN 221*bc36eafdSMike Gerdts AcpiUtSafeStrncat ( 222*bc36eafdSMike Gerdts char *Dest, 223*bc36eafdSMike Gerdts ACPI_SIZE DestSize, 224*bc36eafdSMike Gerdts char *Source, 225*bc36eafdSMike Gerdts ACPI_SIZE MaxTransferLength) 226*bc36eafdSMike Gerdts { 227*bc36eafdSMike Gerdts ACPI_SIZE ActualTransferLength; 228*bc36eafdSMike Gerdts 229*bc36eafdSMike Gerdts 230*bc36eafdSMike Gerdts ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source)); 231*bc36eafdSMike Gerdts 232*bc36eafdSMike Gerdts if ((strlen (Dest) + ActualTransferLength) >= DestSize) 233*bc36eafdSMike Gerdts { 234*bc36eafdSMike Gerdts return (TRUE); 235*bc36eafdSMike Gerdts } 236*bc36eafdSMike Gerdts 237*bc36eafdSMike Gerdts strncat (Dest, Source, MaxTransferLength); 238*bc36eafdSMike Gerdts return (FALSE); 239*bc36eafdSMike Gerdts } 240*bc36eafdSMike Gerdts #endif 241*bc36eafdSMike Gerdts 242*bc36eafdSMike Gerdts 243*bc36eafdSMike Gerdts /******************************************************************************* 244*bc36eafdSMike Gerdts * 245*bc36eafdSMike Gerdts * FUNCTION: AcpiUtStrtoul64 246*bc36eafdSMike Gerdts * 247*bc36eafdSMike Gerdts * PARAMETERS: String - Null terminated string 248*bc36eafdSMike Gerdts * Base - Radix of the string: 16 or 10 or 249*bc36eafdSMike Gerdts * ACPI_ANY_BASE 250*bc36eafdSMike Gerdts * MaxIntegerByteWidth - Maximum allowable integer,in bytes: 251*bc36eafdSMike Gerdts * 4 or 8 (32 or 64 bits) 252*bc36eafdSMike Gerdts * RetInteger - Where the converted integer is 253*bc36eafdSMike Gerdts * returned 254*bc36eafdSMike Gerdts * 255*bc36eafdSMike Gerdts * RETURN: Status and Converted value 256*bc36eafdSMike Gerdts * 257*bc36eafdSMike Gerdts * DESCRIPTION: Convert a string into an unsigned value. Performs either a 258*bc36eafdSMike Gerdts * 32-bit or 64-bit conversion, depending on the input integer 259*bc36eafdSMike Gerdts * size (often the current mode of the interpreter). 260*bc36eafdSMike Gerdts * 261*bc36eafdSMike Gerdts * NOTES: Negative numbers are not supported, as they are not supported 262*bc36eafdSMike Gerdts * by ACPI. 263*bc36eafdSMike Gerdts * 264*bc36eafdSMike Gerdts * AcpiGbl_IntegerByteWidth should be set to the proper width. 265*bc36eafdSMike Gerdts * For the core ACPICA code, this width depends on the DSDT 266*bc36eafdSMike Gerdts * version. For iASL, the default byte width is always 8 for the 267*bc36eafdSMike Gerdts * parser, but error checking is performed later to flag cases 268*bc36eafdSMike Gerdts * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. 269*bc36eafdSMike Gerdts * 270*bc36eafdSMike Gerdts * Does not support Octal strings, not needed at this time. 271*bc36eafdSMike Gerdts * 272*bc36eafdSMike Gerdts ******************************************************************************/ 273*bc36eafdSMike Gerdts 274*bc36eafdSMike Gerdts ACPI_STATUS 275*bc36eafdSMike Gerdts AcpiUtStrtoul64 ( 276*bc36eafdSMike Gerdts char *String, 277*bc36eafdSMike Gerdts UINT32 Base, 278*bc36eafdSMike Gerdts UINT32 MaxIntegerByteWidth, 279*bc36eafdSMike Gerdts UINT64 *RetInteger) 280*bc36eafdSMike Gerdts { 281*bc36eafdSMike Gerdts UINT32 ThisDigit = 0; 282*bc36eafdSMike Gerdts UINT64 ReturnValue = 0; 283*bc36eafdSMike Gerdts UINT64 Quotient; 284*bc36eafdSMike Gerdts UINT64 Dividend; 285*bc36eafdSMike Gerdts UINT8 ValidDigits = 0; 286*bc36eafdSMike Gerdts UINT8 SignOf0x = 0; 287*bc36eafdSMike Gerdts UINT8 Term = 0; 288*bc36eafdSMike Gerdts 289*bc36eafdSMike Gerdts 290*bc36eafdSMike Gerdts ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String); 291*bc36eafdSMike Gerdts 292*bc36eafdSMike Gerdts 293*bc36eafdSMike Gerdts switch (Base) 294*bc36eafdSMike Gerdts { 295*bc36eafdSMike Gerdts case ACPI_ANY_BASE: 296*bc36eafdSMike Gerdts case 10: 297*bc36eafdSMike Gerdts case 16: 298*bc36eafdSMike Gerdts 299*bc36eafdSMike Gerdts break; 300*bc36eafdSMike Gerdts 301*bc36eafdSMike Gerdts default: 302*bc36eafdSMike Gerdts 303*bc36eafdSMike Gerdts /* Invalid Base */ 304*bc36eafdSMike Gerdts 305*bc36eafdSMike Gerdts return_ACPI_STATUS (AE_BAD_PARAMETER); 306*bc36eafdSMike Gerdts } 307*bc36eafdSMike Gerdts 308*bc36eafdSMike Gerdts if (!String) 309*bc36eafdSMike Gerdts { 310*bc36eafdSMike Gerdts goto ErrorExit; 311*bc36eafdSMike Gerdts } 312*bc36eafdSMike Gerdts 313*bc36eafdSMike Gerdts /* Skip over any white space in the buffer */ 314*bc36eafdSMike Gerdts 315*bc36eafdSMike Gerdts while ((*String) && (isspace ((int) *String) || *String == '\t')) 316*bc36eafdSMike Gerdts { 317*bc36eafdSMike Gerdts String++; 318*bc36eafdSMike Gerdts } 319*bc36eafdSMike Gerdts 320*bc36eafdSMike Gerdts if (Base == ACPI_ANY_BASE) 321*bc36eafdSMike Gerdts { 322*bc36eafdSMike Gerdts /* 323*bc36eafdSMike Gerdts * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'. 324*bc36eafdSMike Gerdts * We need to determine if it is decimal or hexadecimal. 325*bc36eafdSMike Gerdts */ 326*bc36eafdSMike Gerdts if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x')) 327*bc36eafdSMike Gerdts { 328*bc36eafdSMike Gerdts SignOf0x = 1; 329*bc36eafdSMike Gerdts Base = 16; 330*bc36eafdSMike Gerdts 331*bc36eafdSMike Gerdts /* Skip over the leading '0x' */ 332*bc36eafdSMike Gerdts String += 2; 333*bc36eafdSMike Gerdts } 334*bc36eafdSMike Gerdts else 335*bc36eafdSMike Gerdts { 336*bc36eafdSMike Gerdts Base = 10; 337*bc36eafdSMike Gerdts } 338*bc36eafdSMike Gerdts } 339*bc36eafdSMike Gerdts 340*bc36eafdSMike Gerdts /* Any string left? Check that '0x' is not followed by white space. */ 341*bc36eafdSMike Gerdts 342*bc36eafdSMike Gerdts if (!(*String) || isspace ((int) *String) || *String == '\t') 343*bc36eafdSMike Gerdts { 344*bc36eafdSMike Gerdts if (Base == ACPI_ANY_BASE) 345*bc36eafdSMike Gerdts { 346*bc36eafdSMike Gerdts goto ErrorExit; 347*bc36eafdSMike Gerdts } 348*bc36eafdSMike Gerdts else 349*bc36eafdSMike Gerdts { 350*bc36eafdSMike Gerdts goto AllDone; 351*bc36eafdSMike Gerdts } 352*bc36eafdSMike Gerdts } 353*bc36eafdSMike Gerdts 354*bc36eafdSMike Gerdts /* 355*bc36eafdSMike Gerdts * Perform a 32-bit or 64-bit conversion, depending upon the input 356*bc36eafdSMike Gerdts * byte width 357*bc36eafdSMike Gerdts */ 358*bc36eafdSMike Gerdts Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ? 359*bc36eafdSMike Gerdts ACPI_UINT32_MAX : ACPI_UINT64_MAX; 360*bc36eafdSMike Gerdts 361*bc36eafdSMike Gerdts /* Main loop: convert the string to a 32- or 64-bit integer */ 362*bc36eafdSMike Gerdts 363*bc36eafdSMike Gerdts while (*String) 364*bc36eafdSMike Gerdts { 365*bc36eafdSMike Gerdts if (isdigit ((int) *String)) 366*bc36eafdSMike Gerdts { 367*bc36eafdSMike Gerdts /* Convert ASCII 0-9 to Decimal value */ 368*bc36eafdSMike Gerdts 369*bc36eafdSMike Gerdts ThisDigit = ((UINT8) *String) - '0'; 370*bc36eafdSMike Gerdts } 371*bc36eafdSMike Gerdts else if (Base == 10) 372*bc36eafdSMike Gerdts { 373*bc36eafdSMike Gerdts /* Digit is out of range; possible in ToInteger case only */ 374*bc36eafdSMike Gerdts 375*bc36eafdSMike Gerdts Term = 1; 376*bc36eafdSMike Gerdts } 377*bc36eafdSMike Gerdts else 378*bc36eafdSMike Gerdts { 379*bc36eafdSMike Gerdts ThisDigit = (UINT8) toupper ((int) *String); 380*bc36eafdSMike Gerdts if (isxdigit ((int) ThisDigit)) 381*bc36eafdSMike Gerdts { 382*bc36eafdSMike Gerdts /* Convert ASCII Hex char to value */ 383*bc36eafdSMike Gerdts 384*bc36eafdSMike Gerdts ThisDigit = ThisDigit - 'A' + 10; 385*bc36eafdSMike Gerdts } 386*bc36eafdSMike Gerdts else 387*bc36eafdSMike Gerdts { 388*bc36eafdSMike Gerdts Term = 1; 389*bc36eafdSMike Gerdts } 390*bc36eafdSMike Gerdts } 391*bc36eafdSMike Gerdts 392*bc36eafdSMike Gerdts if (Term) 393*bc36eafdSMike Gerdts { 394*bc36eafdSMike Gerdts if (Base == ACPI_ANY_BASE) 395*bc36eafdSMike Gerdts { 396*bc36eafdSMike Gerdts goto ErrorExit; 397*bc36eafdSMike Gerdts } 398*bc36eafdSMike Gerdts else 399*bc36eafdSMike Gerdts { 400*bc36eafdSMike Gerdts break; 401*bc36eafdSMike Gerdts } 402*bc36eafdSMike Gerdts } 403*bc36eafdSMike Gerdts else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 404*bc36eafdSMike Gerdts { 405*bc36eafdSMike Gerdts /* Skip zeros */ 406*bc36eafdSMike Gerdts String++; 407*bc36eafdSMike Gerdts continue; 408*bc36eafdSMike Gerdts } 409*bc36eafdSMike Gerdts 410*bc36eafdSMike Gerdts ValidDigits++; 411*bc36eafdSMike Gerdts 412*bc36eafdSMike Gerdts if (SignOf0x && ((ValidDigits > 16) || 413*bc36eafdSMike Gerdts ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH)))) 414*bc36eafdSMike Gerdts { 415*bc36eafdSMike Gerdts /* 416*bc36eafdSMike Gerdts * This is ToInteger operation case. 417*bc36eafdSMike Gerdts * No restrictions for string-to-integer conversion, 418*bc36eafdSMike Gerdts * see ACPI spec. 419*bc36eafdSMike Gerdts */ 420*bc36eafdSMike Gerdts goto ErrorExit; 421*bc36eafdSMike Gerdts } 422*bc36eafdSMike Gerdts 423*bc36eafdSMike Gerdts /* Divide the digit into the correct position */ 424*bc36eafdSMike Gerdts 425*bc36eafdSMike Gerdts (void) AcpiUtShortDivide ( 426*bc36eafdSMike Gerdts (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); 427*bc36eafdSMike Gerdts 428*bc36eafdSMike Gerdts if (ReturnValue > Quotient) 429*bc36eafdSMike Gerdts { 430*bc36eafdSMike Gerdts if (Base == ACPI_ANY_BASE) 431*bc36eafdSMike Gerdts { 432*bc36eafdSMike Gerdts goto ErrorExit; 433*bc36eafdSMike Gerdts } 434*bc36eafdSMike Gerdts else 435*bc36eafdSMike Gerdts { 436*bc36eafdSMike Gerdts break; 437*bc36eafdSMike Gerdts } 438*bc36eafdSMike Gerdts } 439*bc36eafdSMike Gerdts 440*bc36eafdSMike Gerdts ReturnValue *= Base; 441*bc36eafdSMike Gerdts ReturnValue += ThisDigit; 442*bc36eafdSMike Gerdts String++; 443*bc36eafdSMike Gerdts } 444*bc36eafdSMike Gerdts 445*bc36eafdSMike Gerdts /* All done, normal exit */ 446*bc36eafdSMike Gerdts 447*bc36eafdSMike Gerdts AllDone: 448*bc36eafdSMike Gerdts 449*bc36eafdSMike Gerdts ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 450*bc36eafdSMike Gerdts ACPI_FORMAT_UINT64 (ReturnValue))); 451*bc36eafdSMike Gerdts 452*bc36eafdSMike Gerdts *RetInteger = ReturnValue; 453*bc36eafdSMike Gerdts return_ACPI_STATUS (AE_OK); 454*bc36eafdSMike Gerdts 455*bc36eafdSMike Gerdts 456*bc36eafdSMike Gerdts ErrorExit: 457*bc36eafdSMike Gerdts 458*bc36eafdSMike Gerdts /* Base was set/validated above (10 or 16) */ 459*bc36eafdSMike Gerdts 460*bc36eafdSMike Gerdts if (Base == 10) 461*bc36eafdSMike Gerdts { 462*bc36eafdSMike Gerdts return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 463*bc36eafdSMike Gerdts } 464*bc36eafdSMike Gerdts else 465*bc36eafdSMike Gerdts { 466*bc36eafdSMike Gerdts return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 467*bc36eafdSMike Gerdts } 468*bc36eafdSMike Gerdts } 469*bc36eafdSMike Gerdts 470*bc36eafdSMike Gerdts 471*bc36eafdSMike Gerdts #ifdef _OBSOLETE_FUNCTIONS 472*bc36eafdSMike Gerdts /* Removed: 01/2016 */ 473*bc36eafdSMike Gerdts 474*bc36eafdSMike Gerdts /******************************************************************************* 475*bc36eafdSMike Gerdts * 476*bc36eafdSMike Gerdts * FUNCTION: strtoul64 477*bc36eafdSMike Gerdts * 478*bc36eafdSMike Gerdts * PARAMETERS: String - Null terminated string 479*bc36eafdSMike Gerdts * Terminater - Where a pointer to the terminating byte 480*bc36eafdSMike Gerdts * is returned 481*bc36eafdSMike Gerdts * Base - Radix of the string 482*bc36eafdSMike Gerdts * 483*bc36eafdSMike Gerdts * RETURN: Converted value 484*bc36eafdSMike Gerdts * 485*bc36eafdSMike Gerdts * DESCRIPTION: Convert a string into an unsigned value. 486*bc36eafdSMike Gerdts * 487*bc36eafdSMike Gerdts ******************************************************************************/ 488*bc36eafdSMike Gerdts 489*bc36eafdSMike Gerdts ACPI_STATUS 490*bc36eafdSMike Gerdts strtoul64 ( 491*bc36eafdSMike Gerdts char *String, 492*bc36eafdSMike Gerdts UINT32 Base, 493*bc36eafdSMike Gerdts UINT64 *RetInteger) 494*bc36eafdSMike Gerdts { 495*bc36eafdSMike Gerdts UINT32 Index; 496*bc36eafdSMike Gerdts UINT32 Sign; 497*bc36eafdSMike Gerdts UINT64 ReturnValue = 0; 498*bc36eafdSMike Gerdts ACPI_STATUS Status = AE_OK; 499*bc36eafdSMike Gerdts 500*bc36eafdSMike Gerdts 501*bc36eafdSMike Gerdts *RetInteger = 0; 502*bc36eafdSMike Gerdts 503*bc36eafdSMike Gerdts switch (Base) 504*bc36eafdSMike Gerdts { 505*bc36eafdSMike Gerdts case 0: 506*bc36eafdSMike Gerdts case 8: 507*bc36eafdSMike Gerdts case 10: 508*bc36eafdSMike Gerdts case 16: 509*bc36eafdSMike Gerdts 510*bc36eafdSMike Gerdts break; 511*bc36eafdSMike Gerdts 512*bc36eafdSMike Gerdts default: 513*bc36eafdSMike Gerdts /* 514*bc36eafdSMike Gerdts * The specified Base parameter is not in the domain of 515*bc36eafdSMike Gerdts * this function: 516*bc36eafdSMike Gerdts */ 517*bc36eafdSMike Gerdts return (AE_BAD_PARAMETER); 518*bc36eafdSMike Gerdts } 519*bc36eafdSMike Gerdts 520*bc36eafdSMike Gerdts /* Skip over any white space in the buffer: */ 521*bc36eafdSMike Gerdts 522*bc36eafdSMike Gerdts while (isspace ((int) *String) || *String == '\t') 523*bc36eafdSMike Gerdts { 524*bc36eafdSMike Gerdts ++String; 525*bc36eafdSMike Gerdts } 526*bc36eafdSMike Gerdts 527*bc36eafdSMike Gerdts /* 528*bc36eafdSMike Gerdts * The buffer may contain an optional plus or minus sign. 529*bc36eafdSMike Gerdts * If it does, then skip over it but remember what is was: 530*bc36eafdSMike Gerdts */ 531*bc36eafdSMike Gerdts if (*String == '-') 532*bc36eafdSMike Gerdts { 533*bc36eafdSMike Gerdts Sign = ACPI_SIGN_NEGATIVE; 534*bc36eafdSMike Gerdts ++String; 535*bc36eafdSMike Gerdts } 536*bc36eafdSMike Gerdts else if (*String == '+') 537*bc36eafdSMike Gerdts { 538*bc36eafdSMike Gerdts ++String; 539*bc36eafdSMike Gerdts Sign = ACPI_SIGN_POSITIVE; 540*bc36eafdSMike Gerdts } 541*bc36eafdSMike Gerdts else 542*bc36eafdSMike Gerdts { 543*bc36eafdSMike Gerdts Sign = ACPI_SIGN_POSITIVE; 544*bc36eafdSMike Gerdts } 545*bc36eafdSMike Gerdts 546*bc36eafdSMike Gerdts /* 547*bc36eafdSMike Gerdts * If the input parameter Base is zero, then we need to 548*bc36eafdSMike Gerdts * determine if it is octal, decimal, or hexadecimal: 549*bc36eafdSMike Gerdts */ 550*bc36eafdSMike Gerdts if (Base == 0) 551*bc36eafdSMike Gerdts { 552*bc36eafdSMike Gerdts if (*String == '0') 553*bc36eafdSMike Gerdts { 554*bc36eafdSMike Gerdts if (tolower ((int) *(++String)) == 'x') 555*bc36eafdSMike Gerdts { 556*bc36eafdSMike Gerdts Base = 16; 557*bc36eafdSMike Gerdts ++String; 558*bc36eafdSMike Gerdts } 559*bc36eafdSMike Gerdts else 560*bc36eafdSMike Gerdts { 561*bc36eafdSMike Gerdts Base = 8; 562*bc36eafdSMike Gerdts } 563*bc36eafdSMike Gerdts } 564*bc36eafdSMike Gerdts else 565*bc36eafdSMike Gerdts { 566*bc36eafdSMike Gerdts Base = 10; 567*bc36eafdSMike Gerdts } 568*bc36eafdSMike Gerdts } 569*bc36eafdSMike Gerdts 570*bc36eafdSMike Gerdts /* 571*bc36eafdSMike Gerdts * For octal and hexadecimal bases, skip over the leading 572*bc36eafdSMike Gerdts * 0 or 0x, if they are present. 573*bc36eafdSMike Gerdts */ 574*bc36eafdSMike Gerdts if (Base == 8 && *String == '0') 575*bc36eafdSMike Gerdts { 576*bc36eafdSMike Gerdts String++; 577*bc36eafdSMike Gerdts } 578*bc36eafdSMike Gerdts 579*bc36eafdSMike Gerdts if (Base == 16 && 580*bc36eafdSMike Gerdts *String == '0' && 581*bc36eafdSMike Gerdts tolower ((int) *(++String)) == 'x') 582*bc36eafdSMike Gerdts { 583*bc36eafdSMike Gerdts String++; 584*bc36eafdSMike Gerdts } 585*bc36eafdSMike Gerdts 586*bc36eafdSMike Gerdts /* Main loop: convert the string to an unsigned long */ 587*bc36eafdSMike Gerdts 588*bc36eafdSMike Gerdts while (*String) 589*bc36eafdSMike Gerdts { 590*bc36eafdSMike Gerdts if (isdigit ((int) *String)) 591*bc36eafdSMike Gerdts { 592*bc36eafdSMike Gerdts Index = ((UINT8) *String) - '0'; 593*bc36eafdSMike Gerdts } 594*bc36eafdSMike Gerdts else 595*bc36eafdSMike Gerdts { 596*bc36eafdSMike Gerdts Index = (UINT8) toupper ((int) *String); 597*bc36eafdSMike Gerdts if (isupper ((int) Index)) 598*bc36eafdSMike Gerdts { 599*bc36eafdSMike Gerdts Index = Index - 'A' + 10; 600*bc36eafdSMike Gerdts } 601*bc36eafdSMike Gerdts else 602*bc36eafdSMike Gerdts { 603*bc36eafdSMike Gerdts goto ErrorExit; 604*bc36eafdSMike Gerdts } 605*bc36eafdSMike Gerdts } 606*bc36eafdSMike Gerdts 607*bc36eafdSMike Gerdts if (Index >= Base) 608*bc36eafdSMike Gerdts { 609*bc36eafdSMike Gerdts goto ErrorExit; 610*bc36eafdSMike Gerdts } 611*bc36eafdSMike Gerdts 612*bc36eafdSMike Gerdts /* Check to see if value is out of range: */ 613*bc36eafdSMike Gerdts 614*bc36eafdSMike Gerdts if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 615*bc36eafdSMike Gerdts (UINT64) Base)) 616*bc36eafdSMike Gerdts { 617*bc36eafdSMike Gerdts goto ErrorExit; 618*bc36eafdSMike Gerdts } 619*bc36eafdSMike Gerdts else 620*bc36eafdSMike Gerdts { 621*bc36eafdSMike Gerdts ReturnValue *= Base; 622*bc36eafdSMike Gerdts ReturnValue += Index; 623*bc36eafdSMike Gerdts } 624*bc36eafdSMike Gerdts 625*bc36eafdSMike Gerdts ++String; 626*bc36eafdSMike Gerdts } 627*bc36eafdSMike Gerdts 628*bc36eafdSMike Gerdts 629*bc36eafdSMike Gerdts /* If a minus sign was present, then "the conversion is negated": */ 630*bc36eafdSMike Gerdts 631*bc36eafdSMike Gerdts if (Sign == ACPI_SIGN_NEGATIVE) 632*bc36eafdSMike Gerdts { 633*bc36eafdSMike Gerdts ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 634*bc36eafdSMike Gerdts } 635*bc36eafdSMike Gerdts 636*bc36eafdSMike Gerdts *RetInteger = ReturnValue; 637*bc36eafdSMike Gerdts return (Status); 638*bc36eafdSMike Gerdts 639*bc36eafdSMike Gerdts 640*bc36eafdSMike Gerdts ErrorExit: 641*bc36eafdSMike Gerdts switch (Base) 642*bc36eafdSMike Gerdts { 643*bc36eafdSMike Gerdts case 8: 644*bc36eafdSMike Gerdts 645*bc36eafdSMike Gerdts Status = AE_BAD_OCTAL_CONSTANT; 646*bc36eafdSMike Gerdts break; 647*bc36eafdSMike Gerdts 648*bc36eafdSMike Gerdts case 10: 649*bc36eafdSMike Gerdts 650*bc36eafdSMike Gerdts Status = AE_BAD_DECIMAL_CONSTANT; 651*bc36eafdSMike Gerdts break; 652*bc36eafdSMike Gerdts 653*bc36eafdSMike Gerdts case 16: 654*bc36eafdSMike Gerdts 655*bc36eafdSMike Gerdts Status = AE_BAD_HEX_CONSTANT; 656*bc36eafdSMike Gerdts break; 657*bc36eafdSMike Gerdts 658*bc36eafdSMike Gerdts default: 659*bc36eafdSMike Gerdts 660*bc36eafdSMike Gerdts /* Base validated above */ 661*bc36eafdSMike Gerdts 662*bc36eafdSMike Gerdts break; 663*bc36eafdSMike Gerdts } 664*bc36eafdSMike Gerdts 665*bc36eafdSMike Gerdts return (Status); 666*bc36eafdSMike Gerdts } 667*bc36eafdSMike Gerdts #endif 668