1 /******************************************************************************* 2 * 3 * Module Name: utstring - Common functions for strings and characters 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 45 #define __UTSTRING_C__ 46 47 #include <contrib/dev/acpica/include/acpi.h> 48 #include <contrib/dev/acpica/include/accommon.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 51 52 #define _COMPONENT ACPI_UTILITIES 53 ACPI_MODULE_NAME ("utstring") 54 55 56 /* 57 * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit 58 * version of strtoul. 59 */ 60 61 #ifdef ACPI_ASL_COMPILER 62 /******************************************************************************* 63 * 64 * FUNCTION: AcpiUtStrlwr (strlwr) 65 * 66 * PARAMETERS: SrcString - The source string to convert 67 * 68 * RETURN: None 69 * 70 * DESCRIPTION: Convert string to lowercase 71 * 72 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 73 * 74 ******************************************************************************/ 75 76 void 77 AcpiUtStrlwr ( 78 char *SrcString) 79 { 80 char *String; 81 82 83 ACPI_FUNCTION_ENTRY (); 84 85 86 if (!SrcString) 87 { 88 return; 89 } 90 91 /* Walk entire string, lowercasing the letters */ 92 93 for (String = SrcString; *String; String++) 94 { 95 *String = (char) ACPI_TOLOWER (*String); 96 } 97 98 return; 99 } 100 101 102 /****************************************************************************** 103 * 104 * FUNCTION: AcpiUtStricmp (stricmp) 105 * 106 * PARAMETERS: String1 - first string to compare 107 * String2 - second string to compare 108 * 109 * RETURN: int that signifies string relationship. Zero means strings 110 * are equal. 111 * 112 * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare 113 * strings with no case sensitivity) 114 * 115 ******************************************************************************/ 116 117 int 118 AcpiUtStricmp ( 119 char *String1, 120 char *String2) 121 { 122 int c1; 123 int c2; 124 125 126 do 127 { 128 c1 = tolower ((int) *String1); 129 c2 = tolower ((int) *String2); 130 131 String1++; 132 String2++; 133 } 134 while ((c1 == c2) && (c1)); 135 136 return (c1 - c2); 137 } 138 #endif 139 140 141 /******************************************************************************* 142 * 143 * FUNCTION: AcpiUtStrupr (strupr) 144 * 145 * PARAMETERS: SrcString - The source string to convert 146 * 147 * RETURN: None 148 * 149 * DESCRIPTION: Convert string to uppercase 150 * 151 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 152 * 153 ******************************************************************************/ 154 155 void 156 AcpiUtStrupr ( 157 char *SrcString) 158 { 159 char *String; 160 161 162 ACPI_FUNCTION_ENTRY (); 163 164 165 if (!SrcString) 166 { 167 return; 168 } 169 170 /* Walk entire string, uppercasing the letters */ 171 172 for (String = SrcString; *String; String++) 173 { 174 *String = (char) ACPI_TOUPPER (*String); 175 } 176 177 return; 178 } 179 180 181 /******************************************************************************* 182 * 183 * FUNCTION: AcpiUtStrtoul64 184 * 185 * PARAMETERS: String - Null terminated string 186 * Base - Radix of the string: 16 or ACPI_ANY_BASE; 187 * ACPI_ANY_BASE means 'in behalf of ToInteger' 188 * RetInteger - Where the converted integer is returned 189 * 190 * RETURN: Status and Converted value 191 * 192 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 193 * 32-bit or 64-bit conversion, depending on the current mode 194 * of the interpreter. 195 * NOTE: Does not support Octal strings, not needed. 196 * 197 ******************************************************************************/ 198 199 ACPI_STATUS 200 AcpiUtStrtoul64 ( 201 char *String, 202 UINT32 Base, 203 UINT64 *RetInteger) 204 { 205 UINT32 ThisDigit = 0; 206 UINT64 ReturnValue = 0; 207 UINT64 Quotient; 208 UINT64 Dividend; 209 UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 210 UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 211 UINT8 ValidDigits = 0; 212 UINT8 SignOf0x = 0; 213 UINT8 Term = 0; 214 215 216 ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 217 218 219 switch (Base) 220 { 221 case ACPI_ANY_BASE: 222 case 16: 223 224 break; 225 226 default: 227 228 /* Invalid Base */ 229 230 return_ACPI_STATUS (AE_BAD_PARAMETER); 231 } 232 233 if (!String) 234 { 235 goto ErrorExit; 236 } 237 238 /* Skip over any white space in the buffer */ 239 240 while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 241 { 242 String++; 243 } 244 245 if (ToIntegerOp) 246 { 247 /* 248 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 249 * We need to determine if it is decimal or hexadecimal. 250 */ 251 if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 252 { 253 SignOf0x = 1; 254 Base = 16; 255 256 /* Skip over the leading '0x' */ 257 String += 2; 258 } 259 else 260 { 261 Base = 10; 262 } 263 } 264 265 /* Any string left? Check that '0x' is not followed by white space. */ 266 267 if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 268 { 269 if (ToIntegerOp) 270 { 271 goto ErrorExit; 272 } 273 else 274 { 275 goto AllDone; 276 } 277 } 278 279 /* 280 * Perform a 32-bit or 64-bit conversion, depending upon the current 281 * execution mode of the interpreter 282 */ 283 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 284 285 /* Main loop: convert the string to a 32- or 64-bit integer */ 286 287 while (*String) 288 { 289 if (ACPI_IS_DIGIT (*String)) 290 { 291 /* Convert ASCII 0-9 to Decimal value */ 292 293 ThisDigit = ((UINT8) *String) - '0'; 294 } 295 else if (Base == 10) 296 { 297 /* Digit is out of range; possible in ToInteger case only */ 298 299 Term = 1; 300 } 301 else 302 { 303 ThisDigit = (UINT8) ACPI_TOUPPER (*String); 304 if (ACPI_IS_XDIGIT ((char) ThisDigit)) 305 { 306 /* Convert ASCII Hex char to value */ 307 308 ThisDigit = ThisDigit - 'A' + 10; 309 } 310 else 311 { 312 Term = 1; 313 } 314 } 315 316 if (Term) 317 { 318 if (ToIntegerOp) 319 { 320 goto ErrorExit; 321 } 322 else 323 { 324 break; 325 } 326 } 327 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 328 { 329 /* Skip zeros */ 330 String++; 331 continue; 332 } 333 334 ValidDigits++; 335 336 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 337 { 338 /* 339 * This is ToInteger operation case. 340 * No any restrictions for string-to-integer conversion, 341 * see ACPI spec. 342 */ 343 goto ErrorExit; 344 } 345 346 /* Divide the digit into the correct position */ 347 348 (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 349 Base, &Quotient, NULL); 350 351 if (ReturnValue > Quotient) 352 { 353 if (ToIntegerOp) 354 { 355 goto ErrorExit; 356 } 357 else 358 { 359 break; 360 } 361 } 362 363 ReturnValue *= Base; 364 ReturnValue += ThisDigit; 365 String++; 366 } 367 368 /* All done, normal exit */ 369 370 AllDone: 371 372 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 373 ACPI_FORMAT_UINT64 (ReturnValue))); 374 375 *RetInteger = ReturnValue; 376 return_ACPI_STATUS (AE_OK); 377 378 379 ErrorExit: 380 /* Base was set/validated above */ 381 382 if (Base == 10) 383 { 384 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 385 } 386 else 387 { 388 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 389 } 390 } 391 392 393 /******************************************************************************* 394 * 395 * FUNCTION: AcpiUtPrintString 396 * 397 * PARAMETERS: String - Null terminated ASCII string 398 * MaxLength - Maximum output length. Used to constrain the 399 * length of strings during debug output only. 400 * 401 * RETURN: None 402 * 403 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 404 * sequences. 405 * 406 ******************************************************************************/ 407 408 void 409 AcpiUtPrintString ( 410 char *String, 411 UINT16 MaxLength) 412 { 413 UINT32 i; 414 415 416 if (!String) 417 { 418 AcpiOsPrintf ("<\"NULL STRING PTR\">"); 419 return; 420 } 421 422 AcpiOsPrintf ("\""); 423 for (i = 0; String[i] && (i < MaxLength); i++) 424 { 425 /* Escape sequences */ 426 427 switch (String[i]) 428 { 429 case 0x07: 430 431 AcpiOsPrintf ("\\a"); /* BELL */ 432 break; 433 434 case 0x08: 435 436 AcpiOsPrintf ("\\b"); /* BACKSPACE */ 437 break; 438 439 case 0x0C: 440 441 AcpiOsPrintf ("\\f"); /* FORMFEED */ 442 break; 443 444 case 0x0A: 445 446 AcpiOsPrintf ("\\n"); /* LINEFEED */ 447 break; 448 449 case 0x0D: 450 451 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 452 break; 453 454 case 0x09: 455 456 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 457 break; 458 459 case 0x0B: 460 461 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 462 break; 463 464 case '\'': /* Single Quote */ 465 case '\"': /* Double Quote */ 466 case '\\': /* Backslash */ 467 468 AcpiOsPrintf ("\\%c", (int) String[i]); 469 break; 470 471 default: 472 473 /* Check for printable character or hex escape */ 474 475 if (ACPI_IS_PRINT (String[i])) 476 { 477 /* This is a normal character */ 478 479 AcpiOsPrintf ("%c", (int) String[i]); 480 } 481 else 482 { 483 /* All others will be Hex escapes */ 484 485 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 486 } 487 break; 488 } 489 } 490 AcpiOsPrintf ("\""); 491 492 if (i == MaxLength && String[i]) 493 { 494 AcpiOsPrintf ("..."); 495 } 496 } 497 498 499 /******************************************************************************* 500 * 501 * FUNCTION: AcpiUtValidAcpiChar 502 * 503 * PARAMETERS: Char - The character to be examined 504 * Position - Byte position (0-3) 505 * 506 * RETURN: TRUE if the character is valid, FALSE otherwise 507 * 508 * DESCRIPTION: Check for a valid ACPI character. Must be one of: 509 * 1) Upper case alpha 510 * 2) numeric 511 * 3) underscore 512 * 513 * We allow a '!' as the last character because of the ASF! table 514 * 515 ******************************************************************************/ 516 517 BOOLEAN 518 AcpiUtValidAcpiChar ( 519 char Character, 520 UINT32 Position) 521 { 522 523 if (!((Character >= 'A' && Character <= 'Z') || 524 (Character >= '0' && Character <= '9') || 525 (Character == '_'))) 526 { 527 /* Allow a '!' in the last position */ 528 529 if (Character == '!' && Position == 3) 530 { 531 return (TRUE); 532 } 533 534 return (FALSE); 535 } 536 537 return (TRUE); 538 } 539 540 541 /******************************************************************************* 542 * 543 * FUNCTION: AcpiUtValidAcpiName 544 * 545 * PARAMETERS: Name - The name to be examined. Does not have to 546 * be NULL terminated string. 547 * 548 * RETURN: TRUE if the name is valid, FALSE otherwise 549 * 550 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 551 * 1) Upper case alpha 552 * 2) numeric 553 * 3) underscore 554 * 555 ******************************************************************************/ 556 557 BOOLEAN 558 AcpiUtValidAcpiName ( 559 char *Name) 560 { 561 UINT32 i; 562 563 564 ACPI_FUNCTION_ENTRY (); 565 566 567 for (i = 0; i < ACPI_NAME_SIZE; i++) 568 { 569 if (!AcpiUtValidAcpiChar (Name[i], i)) 570 { 571 return (FALSE); 572 } 573 } 574 575 return (TRUE); 576 } 577 578 579 /******************************************************************************* 580 * 581 * FUNCTION: AcpiUtRepairName 582 * 583 * PARAMETERS: Name - The ACPI name to be repaired 584 * 585 * RETURN: Repaired version of the name 586 * 587 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 588 * return the new name. NOTE: the Name parameter must reside in 589 * read/write memory, cannot be a const. 590 * 591 * An ACPI Name must consist of valid ACPI characters. We will repair the name 592 * if necessary because we don't want to abort because of this, but we want 593 * all namespace names to be printable. A warning message is appropriate. 594 * 595 * This issue came up because there are in fact machines that exhibit 596 * this problem, and we want to be able to enable ACPI support for them, 597 * even though there are a few bad names. 598 * 599 ******************************************************************************/ 600 601 void 602 AcpiUtRepairName ( 603 char *Name) 604 { 605 UINT32 i; 606 BOOLEAN FoundBadChar = FALSE; 607 UINT32 OriginalName; 608 609 610 ACPI_FUNCTION_NAME (UtRepairName); 611 612 613 ACPI_MOVE_NAME (&OriginalName, Name); 614 615 /* Check each character in the name */ 616 617 for (i = 0; i < ACPI_NAME_SIZE; i++) 618 { 619 if (AcpiUtValidAcpiChar (Name[i], i)) 620 { 621 continue; 622 } 623 624 /* 625 * Replace a bad character with something printable, yet technically 626 * still invalid. This prevents any collisions with existing "good" 627 * names in the namespace. 628 */ 629 Name[i] = '*'; 630 FoundBadChar = TRUE; 631 } 632 633 if (FoundBadChar) 634 { 635 /* Report warning only if in strict mode or debug mode */ 636 637 if (!AcpiGbl_EnableInterpreterSlack) 638 { 639 ACPI_WARNING ((AE_INFO, 640 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 641 OriginalName, Name)); 642 } 643 else 644 { 645 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 646 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 647 OriginalName, Name)); 648 } 649 } 650 } 651 652 653 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 654 /******************************************************************************* 655 * 656 * FUNCTION: UtConvertBackslashes 657 * 658 * PARAMETERS: Pathname - File pathname string to be converted 659 * 660 * RETURN: Modifies the input Pathname 661 * 662 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 663 * the entire input file pathname string. 664 * 665 ******************************************************************************/ 666 667 void 668 UtConvertBackslashes ( 669 char *Pathname) 670 { 671 672 if (!Pathname) 673 { 674 return; 675 } 676 677 while (*Pathname) 678 { 679 if (*Pathname == '\\') 680 { 681 *Pathname = '/'; 682 } 683 684 Pathname++; 685 } 686 } 687 #endif 688