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 ACPI_ANY_BASE; 249 * ACPI_ANY_BASE means 'in behalf of ToInteger' 250 * RetInteger - Where the converted integer is returned 251 * 252 * RETURN: Status and Converted value 253 * 254 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 255 * 32-bit or 64-bit conversion, depending on the current mode 256 * of the interpreter. 257 * 258 * NOTES: AcpiGbl_IntegerByteWidth should be set to the proper width. 259 * For the core ACPICA code, this width depends on the DSDT 260 * version. For iASL, the default byte width is always 8. 261 * 262 * Does not support Octal strings, not needed at this time. 263 * 264 * There is an earlier version of the function after this one, 265 * below. It is slightly different than this one, and the two 266 * may eventually may need to be merged. (01/2016). 267 * 268 ******************************************************************************/ 269 270 ACPI_STATUS 271 AcpiUtStrtoul64 ( 272 char *String, 273 UINT32 Base, 274 UINT64 *RetInteger) 275 { 276 UINT32 ThisDigit = 0; 277 UINT64 ReturnValue = 0; 278 UINT64 Quotient; 279 UINT64 Dividend; 280 UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 281 UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 282 UINT8 ValidDigits = 0; 283 UINT8 SignOf0x = 0; 284 UINT8 Term = 0; 285 286 287 ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String); 288 289 290 switch (Base) 291 { 292 case ACPI_ANY_BASE: 293 case 16: 294 295 break; 296 297 default: 298 299 /* Invalid Base */ 300 301 return_ACPI_STATUS (AE_BAD_PARAMETER); 302 } 303 304 if (!String) 305 { 306 goto ErrorExit; 307 } 308 309 /* Skip over any white space in the buffer */ 310 311 while ((*String) && (isspace ((int) *String) || *String == '\t')) 312 { 313 String++; 314 } 315 316 if (ToIntegerOp) 317 { 318 /* 319 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 320 * We need to determine if it is decimal or hexadecimal. 321 */ 322 if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x')) 323 { 324 SignOf0x = 1; 325 Base = 16; 326 327 /* Skip over the leading '0x' */ 328 String += 2; 329 } 330 else 331 { 332 Base = 10; 333 } 334 } 335 336 /* Any string left? Check that '0x' is not followed by white space. */ 337 338 if (!(*String) || isspace ((int) *String) || *String == '\t') 339 { 340 if (ToIntegerOp) 341 { 342 goto ErrorExit; 343 } 344 else 345 { 346 goto AllDone; 347 } 348 } 349 350 /* 351 * Perform a 32-bit or 64-bit conversion, depending upon the current 352 * execution mode of the interpreter 353 */ 354 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 355 356 /* Main loop: convert the string to a 32- or 64-bit integer */ 357 358 while (*String) 359 { 360 if (isdigit ((int) *String)) 361 { 362 /* Convert ASCII 0-9 to Decimal value */ 363 364 ThisDigit = ((UINT8) *String) - '0'; 365 } 366 else if (Base == 10) 367 { 368 /* Digit is out of range; possible in ToInteger case only */ 369 370 Term = 1; 371 } 372 else 373 { 374 ThisDigit = (UINT8) toupper ((int) *String); 375 if (isxdigit ((int) ThisDigit)) 376 { 377 /* Convert ASCII Hex char to value */ 378 379 ThisDigit = ThisDigit - 'A' + 10; 380 } 381 else 382 { 383 Term = 1; 384 } 385 } 386 387 if (Term) 388 { 389 if (ToIntegerOp) 390 { 391 goto ErrorExit; 392 } 393 else 394 { 395 break; 396 } 397 } 398 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 399 { 400 /* Skip zeros */ 401 String++; 402 continue; 403 } 404 405 ValidDigits++; 406 407 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 408 { 409 /* 410 * This is ToInteger operation case. 411 * No any restrictions for string-to-integer conversion, 412 * see ACPI spec. 413 */ 414 goto ErrorExit; 415 } 416 417 /* Divide the digit into the correct position */ 418 419 (void) AcpiUtShortDivide ( 420 (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); 421 422 if (ReturnValue > Quotient) 423 { 424 if (ToIntegerOp) 425 { 426 goto ErrorExit; 427 } 428 else 429 { 430 break; 431 } 432 } 433 434 ReturnValue *= Base; 435 ReturnValue += ThisDigit; 436 String++; 437 } 438 439 /* All done, normal exit */ 440 441 AllDone: 442 443 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 444 ACPI_FORMAT_UINT64 (ReturnValue))); 445 446 *RetInteger = ReturnValue; 447 return_ACPI_STATUS (AE_OK); 448 449 450 ErrorExit: 451 /* Base was set/validated above */ 452 453 if (Base == 10) 454 { 455 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 456 } 457 else 458 { 459 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 460 } 461 } 462 463 #ifdef _OBSOLETE_FUNCTIONS 464 /* TBD: use version in ACPICA main code base? */ 465 /* DONE: 01/2016 */ 466 467 /******************************************************************************* 468 * 469 * FUNCTION: strtoul64 470 * 471 * PARAMETERS: String - Null terminated string 472 * Terminater - Where a pointer to the terminating byte 473 * is returned 474 * Base - Radix of the string 475 * 476 * RETURN: Converted value 477 * 478 * DESCRIPTION: Convert a string into an unsigned value. 479 * 480 ******************************************************************************/ 481 482 ACPI_STATUS 483 strtoul64 ( 484 char *String, 485 UINT32 Base, 486 UINT64 *RetInteger) 487 { 488 UINT32 Index; 489 UINT32 Sign; 490 UINT64 ReturnValue = 0; 491 ACPI_STATUS Status = AE_OK; 492 493 494 *RetInteger = 0; 495 496 switch (Base) 497 { 498 case 0: 499 case 8: 500 case 10: 501 case 16: 502 503 break; 504 505 default: 506 /* 507 * The specified Base parameter is not in the domain of 508 * this function: 509 */ 510 return (AE_BAD_PARAMETER); 511 } 512 513 /* Skip over any white space in the buffer: */ 514 515 while (isspace ((int) *String) || *String == '\t') 516 { 517 ++String; 518 } 519 520 /* 521 * The buffer may contain an optional plus or minus sign. 522 * If it does, then skip over it but remember what is was: 523 */ 524 if (*String == '-') 525 { 526 Sign = ACPI_SIGN_NEGATIVE; 527 ++String; 528 } 529 else if (*String == '+') 530 { 531 ++String; 532 Sign = ACPI_SIGN_POSITIVE; 533 } 534 else 535 { 536 Sign = ACPI_SIGN_POSITIVE; 537 } 538 539 /* 540 * If the input parameter Base is zero, then we need to 541 * determine if it is octal, decimal, or hexadecimal: 542 */ 543 if (Base == 0) 544 { 545 if (*String == '0') 546 { 547 if (tolower ((int) *(++String)) == 'x') 548 { 549 Base = 16; 550 ++String; 551 } 552 else 553 { 554 Base = 8; 555 } 556 } 557 else 558 { 559 Base = 10; 560 } 561 } 562 563 /* 564 * For octal and hexadecimal bases, skip over the leading 565 * 0 or 0x, if they are present. 566 */ 567 if (Base == 8 && *String == '0') 568 { 569 String++; 570 } 571 572 if (Base == 16 && 573 *String == '0' && 574 tolower ((int) *(++String)) == 'x') 575 { 576 String++; 577 } 578 579 /* Main loop: convert the string to an unsigned long */ 580 581 while (*String) 582 { 583 if (isdigit ((int) *String)) 584 { 585 Index = ((UINT8) *String) - '0'; 586 } 587 else 588 { 589 Index = (UINT8) toupper ((int) *String); 590 if (isupper ((int) Index)) 591 { 592 Index = Index - 'A' + 10; 593 } 594 else 595 { 596 goto ErrorExit; 597 } 598 } 599 600 if (Index >= Base) 601 { 602 goto ErrorExit; 603 } 604 605 /* Check to see if value is out of range: */ 606 607 if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 608 (UINT64) Base)) 609 { 610 goto ErrorExit; 611 } 612 else 613 { 614 ReturnValue *= Base; 615 ReturnValue += Index; 616 } 617 618 ++String; 619 } 620 621 622 /* If a minus sign was present, then "the conversion is negated": */ 623 624 if (Sign == ACPI_SIGN_NEGATIVE) 625 { 626 ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 627 } 628 629 *RetInteger = ReturnValue; 630 return (Status); 631 632 633 ErrorExit: 634 switch (Base) 635 { 636 case 8: 637 638 Status = AE_BAD_OCTAL_CONSTANT; 639 break; 640 641 case 10: 642 643 Status = AE_BAD_DECIMAL_CONSTANT; 644 break; 645 646 case 16: 647 648 Status = AE_BAD_HEX_CONSTANT; 649 break; 650 651 default: 652 653 /* Base validated above */ 654 655 break; 656 } 657 658 return (Status); 659 } 660 #endif 661