utstring.c revision 245582
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 76void 77AcpiUtStrlwr ( 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 117int 118AcpiUtStricmp ( 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 155void 156AcpiUtStrupr ( 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 199ACPI_STATUS 200AcpiUtStrtoul64 ( 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 break; 224 225 default: 226 /* Invalid Base */ 227 return_ACPI_STATUS (AE_BAD_PARAMETER); 228 } 229 230 if (!String) 231 { 232 goto ErrorExit; 233 } 234 235 /* Skip over any white space in the buffer */ 236 237 while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 238 { 239 String++; 240 } 241 242 if (ToIntegerOp) 243 { 244 /* 245 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 246 * We need to determine if it is decimal or hexadecimal. 247 */ 248 if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 249 { 250 SignOf0x = 1; 251 Base = 16; 252 253 /* Skip over the leading '0x' */ 254 String += 2; 255 } 256 else 257 { 258 Base = 10; 259 } 260 } 261 262 /* Any string left? Check that '0x' is not followed by white space. */ 263 264 if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 265 { 266 if (ToIntegerOp) 267 { 268 goto ErrorExit; 269 } 270 else 271 { 272 goto AllDone; 273 } 274 } 275 276 /* 277 * Perform a 32-bit or 64-bit conversion, depending upon the current 278 * execution mode of the interpreter 279 */ 280 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 281 282 /* Main loop: convert the string to a 32- or 64-bit integer */ 283 284 while (*String) 285 { 286 if (ACPI_IS_DIGIT (*String)) 287 { 288 /* Convert ASCII 0-9 to Decimal value */ 289 290 ThisDigit = ((UINT8) *String) - '0'; 291 } 292 else if (Base == 10) 293 { 294 /* Digit is out of range; possible in ToInteger case only */ 295 296 Term = 1; 297 } 298 else 299 { 300 ThisDigit = (UINT8) ACPI_TOUPPER (*String); 301 if (ACPI_IS_XDIGIT ((char) ThisDigit)) 302 { 303 /* Convert ASCII Hex char to value */ 304 305 ThisDigit = ThisDigit - 'A' + 10; 306 } 307 else 308 { 309 Term = 1; 310 } 311 } 312 313 if (Term) 314 { 315 if (ToIntegerOp) 316 { 317 goto ErrorExit; 318 } 319 else 320 { 321 break; 322 } 323 } 324 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 325 { 326 /* Skip zeros */ 327 String++; 328 continue; 329 } 330 331 ValidDigits++; 332 333 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 334 { 335 /* 336 * This is ToInteger operation case. 337 * No any restrictions for string-to-integer conversion, 338 * see ACPI spec. 339 */ 340 goto ErrorExit; 341 } 342 343 /* Divide the digit into the correct position */ 344 345 (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 346 Base, &Quotient, NULL); 347 348 if (ReturnValue > Quotient) 349 { 350 if (ToIntegerOp) 351 { 352 goto ErrorExit; 353 } 354 else 355 { 356 break; 357 } 358 } 359 360 ReturnValue *= Base; 361 ReturnValue += ThisDigit; 362 String++; 363 } 364 365 /* All done, normal exit */ 366 367AllDone: 368 369 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 370 ACPI_FORMAT_UINT64 (ReturnValue))); 371 372 *RetInteger = ReturnValue; 373 return_ACPI_STATUS (AE_OK); 374 375 376ErrorExit: 377 /* Base was set/validated above */ 378 379 if (Base == 10) 380 { 381 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 382 } 383 else 384 { 385 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 386 } 387} 388 389 390/******************************************************************************* 391 * 392 * FUNCTION: AcpiUtPrintString 393 * 394 * PARAMETERS: String - Null terminated ASCII string 395 * MaxLength - Maximum output length 396 * 397 * RETURN: None 398 * 399 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 400 * sequences. 401 * 402 ******************************************************************************/ 403 404void 405AcpiUtPrintString ( 406 char *String, 407 UINT8 MaxLength) 408{ 409 UINT32 i; 410 411 412 if (!String) 413 { 414 AcpiOsPrintf ("<\"NULL STRING PTR\">"); 415 return; 416 } 417 418 AcpiOsPrintf ("\""); 419 for (i = 0; String[i] && (i < MaxLength); i++) 420 { 421 /* Escape sequences */ 422 423 switch (String[i]) 424 { 425 case 0x07: 426 AcpiOsPrintf ("\\a"); /* BELL */ 427 break; 428 429 case 0x08: 430 AcpiOsPrintf ("\\b"); /* BACKSPACE */ 431 break; 432 433 case 0x0C: 434 AcpiOsPrintf ("\\f"); /* FORMFEED */ 435 break; 436 437 case 0x0A: 438 AcpiOsPrintf ("\\n"); /* LINEFEED */ 439 break; 440 441 case 0x0D: 442 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 443 break; 444 445 case 0x09: 446 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 447 break; 448 449 case 0x0B: 450 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 451 break; 452 453 case '\'': /* Single Quote */ 454 case '\"': /* Double Quote */ 455 case '\\': /* Backslash */ 456 AcpiOsPrintf ("\\%c", (int) String[i]); 457 break; 458 459 default: 460 461 /* Check for printable character or hex escape */ 462 463 if (ACPI_IS_PRINT (String[i])) 464 { 465 /* This is a normal character */ 466 467 AcpiOsPrintf ("%c", (int) String[i]); 468 } 469 else 470 { 471 /* All others will be Hex escapes */ 472 473 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 474 } 475 break; 476 } 477 } 478 AcpiOsPrintf ("\""); 479 480 if (i == MaxLength && String[i]) 481 { 482 AcpiOsPrintf ("..."); 483 } 484} 485 486 487/******************************************************************************* 488 * 489 * FUNCTION: AcpiUtValidAcpiChar 490 * 491 * PARAMETERS: Char - The character to be examined 492 * Position - Byte position (0-3) 493 * 494 * RETURN: TRUE if the character is valid, FALSE otherwise 495 * 496 * DESCRIPTION: Check for a valid ACPI character. Must be one of: 497 * 1) Upper case alpha 498 * 2) numeric 499 * 3) underscore 500 * 501 * We allow a '!' as the last character because of the ASF! table 502 * 503 ******************************************************************************/ 504 505BOOLEAN 506AcpiUtValidAcpiChar ( 507 char Character, 508 UINT32 Position) 509{ 510 511 if (!((Character >= 'A' && Character <= 'Z') || 512 (Character >= '0' && Character <= '9') || 513 (Character == '_'))) 514 { 515 /* Allow a '!' in the last position */ 516 517 if (Character == '!' && Position == 3) 518 { 519 return (TRUE); 520 } 521 522 return (FALSE); 523 } 524 525 return (TRUE); 526} 527 528 529/******************************************************************************* 530 * 531 * FUNCTION: AcpiUtValidAcpiName 532 * 533 * PARAMETERS: Name - The name to be examined 534 * 535 * RETURN: TRUE if the name is valid, FALSE otherwise 536 * 537 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 538 * 1) Upper case alpha 539 * 2) numeric 540 * 3) underscore 541 * 542 ******************************************************************************/ 543 544BOOLEAN 545AcpiUtValidAcpiName ( 546 UINT32 Name) 547{ 548 UINT32 i; 549 550 551 ACPI_FUNCTION_ENTRY (); 552 553 554 for (i = 0; i < ACPI_NAME_SIZE; i++) 555 { 556 if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i)) 557 { 558 return (FALSE); 559 } 560 } 561 562 return (TRUE); 563} 564 565 566/******************************************************************************* 567 * 568 * FUNCTION: AcpiUtRepairName 569 * 570 * PARAMETERS: Name - The ACPI name to be repaired 571 * 572 * RETURN: Repaired version of the name 573 * 574 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 575 * return the new name. NOTE: the Name parameter must reside in 576 * read/write memory, cannot be a const. 577 * 578 * An ACPI Name must consist of valid ACPI characters. We will repair the name 579 * if necessary because we don't want to abort because of this, but we want 580 * all namespace names to be printable. A warning message is appropriate. 581 * 582 * This issue came up because there are in fact machines that exhibit 583 * this problem, and we want to be able to enable ACPI support for them, 584 * even though there are a few bad names. 585 * 586 ******************************************************************************/ 587 588void 589AcpiUtRepairName ( 590 char *Name) 591{ 592 UINT32 i; 593 BOOLEAN FoundBadChar = FALSE; 594 UINT32 OriginalName; 595 596 597 ACPI_FUNCTION_NAME (UtRepairName); 598 599 600 ACPI_MOVE_NAME (&OriginalName, Name); 601 602 /* Check each character in the name */ 603 604 for (i = 0; i < ACPI_NAME_SIZE; i++) 605 { 606 if (AcpiUtValidAcpiChar (Name[i], i)) 607 { 608 continue; 609 } 610 611 /* 612 * Replace a bad character with something printable, yet technically 613 * still invalid. This prevents any collisions with existing "good" 614 * names in the namespace. 615 */ 616 Name[i] = '*'; 617 FoundBadChar = TRUE; 618 } 619 620 if (FoundBadChar) 621 { 622 /* Report warning only if in strict mode or debug mode */ 623 624 if (!AcpiGbl_EnableInterpreterSlack) 625 { 626 ACPI_WARNING ((AE_INFO, 627 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 628 OriginalName, Name)); 629 } 630 else 631 { 632 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 633 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 634 OriginalName, Name)); 635 } 636 } 637} 638 639 640#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 641/******************************************************************************* 642 * 643 * FUNCTION: UtConvertBackslashes 644 * 645 * PARAMETERS: Pathname - File pathname string to be converted 646 * 647 * RETURN: Modifies the input Pathname 648 * 649 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 650 * the entire input file pathname string. 651 * 652 ******************************************************************************/ 653 654void 655UtConvertBackslashes ( 656 char *Pathname) 657{ 658 659 if (!Pathname) 660 { 661 return; 662 } 663 664 while (*Pathname) 665 { 666 if (*Pathname == '\\') 667 { 668 *Pathname = '/'; 669 } 670 671 Pathname++; 672 } 673} 674#endif 675