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