1244971Sjkim/******************************************************************************* 2244971Sjkim * 3244971Sjkim * Module Name: utstring - Common functions for strings and characters 4244971Sjkim * 5244971Sjkim ******************************************************************************/ 6244971Sjkim 7244971Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp. 9244971Sjkim * All rights reserved. 10244971Sjkim * 11244971Sjkim * Redistribution and use in source and binary forms, with or without 12244971Sjkim * modification, are permitted provided that the following conditions 13244971Sjkim * are met: 14244971Sjkim * 1. Redistributions of source code must retain the above copyright 15244971Sjkim * notice, this list of conditions, and the following disclaimer, 16244971Sjkim * without modification. 17244971Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18244971Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19244971Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20244971Sjkim * including a substantially similar Disclaimer requirement for further 21244971Sjkim * binary redistribution. 22244971Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23244971Sjkim * of any contributors may be used to endorse or promote products derived 24244971Sjkim * from this software without specific prior written permission. 25244971Sjkim * 26244971Sjkim * Alternatively, this software may be distributed under the terms of the 27244971Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28244971Sjkim * Software Foundation. 29244971Sjkim * 30244971Sjkim * NO WARRANTY 31244971Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32244971Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33244971Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34244971Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35244971Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36244971Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37244971Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38244971Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39244971Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40244971Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41244971Sjkim * POSSIBILITY OF SUCH DAMAGES. 42244971Sjkim */ 43244971Sjkim 44245582Sjkim#include <contrib/dev/acpica/include/acpi.h> 45245582Sjkim#include <contrib/dev/acpica/include/accommon.h> 46245582Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47244971Sjkim 48244971Sjkim 49244971Sjkim#define _COMPONENT ACPI_UTILITIES 50244971Sjkim ACPI_MODULE_NAME ("utstring") 51244971Sjkim 52244971Sjkim 53244971Sjkim/* 54244971Sjkim * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit 55244971Sjkim * version of strtoul. 56244971Sjkim */ 57244971Sjkim 58244971Sjkim#ifdef ACPI_ASL_COMPILER 59244971Sjkim/******************************************************************************* 60244971Sjkim * 61244971Sjkim * FUNCTION: AcpiUtStrlwr (strlwr) 62244971Sjkim * 63244971Sjkim * PARAMETERS: SrcString - The source string to convert 64244971Sjkim * 65244971Sjkim * RETURN: None 66244971Sjkim * 67244971Sjkim * DESCRIPTION: Convert string to lowercase 68244971Sjkim * 69244971Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 70244971Sjkim * 71244971Sjkim ******************************************************************************/ 72244971Sjkim 73244971Sjkimvoid 74244971SjkimAcpiUtStrlwr ( 75244971Sjkim char *SrcString) 76244971Sjkim{ 77244971Sjkim char *String; 78244971Sjkim 79244971Sjkim 80244971Sjkim ACPI_FUNCTION_ENTRY (); 81244971Sjkim 82244971Sjkim 83244971Sjkim if (!SrcString) 84244971Sjkim { 85244971Sjkim return; 86244971Sjkim } 87244971Sjkim 88244971Sjkim /* Walk entire string, lowercasing the letters */ 89244971Sjkim 90244971Sjkim for (String = SrcString; *String; String++) 91244971Sjkim { 92244971Sjkim *String = (char) ACPI_TOLOWER (*String); 93244971Sjkim } 94244971Sjkim 95244971Sjkim return; 96244971Sjkim} 97244971Sjkim 98244971Sjkim 99244971Sjkim/****************************************************************************** 100244971Sjkim * 101244971Sjkim * FUNCTION: AcpiUtStricmp (stricmp) 102244971Sjkim * 103244971Sjkim * PARAMETERS: String1 - first string to compare 104244971Sjkim * String2 - second string to compare 105244971Sjkim * 106244971Sjkim * RETURN: int that signifies string relationship. Zero means strings 107244971Sjkim * are equal. 108244971Sjkim * 109244971Sjkim * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare 110244971Sjkim * strings with no case sensitivity) 111244971Sjkim * 112244971Sjkim ******************************************************************************/ 113244971Sjkim 114244971Sjkimint 115244971SjkimAcpiUtStricmp ( 116244971Sjkim char *String1, 117244971Sjkim char *String2) 118244971Sjkim{ 119244971Sjkim int c1; 120244971Sjkim int c2; 121244971Sjkim 122244971Sjkim 123244971Sjkim do 124244971Sjkim { 125244971Sjkim c1 = tolower ((int) *String1); 126244971Sjkim c2 = tolower ((int) *String2); 127244971Sjkim 128244971Sjkim String1++; 129244971Sjkim String2++; 130244971Sjkim } 131244971Sjkim while ((c1 == c2) && (c1)); 132244971Sjkim 133244971Sjkim return (c1 - c2); 134244971Sjkim} 135244971Sjkim#endif 136244971Sjkim 137244971Sjkim 138244971Sjkim/******************************************************************************* 139244971Sjkim * 140244971Sjkim * FUNCTION: AcpiUtStrupr (strupr) 141244971Sjkim * 142244971Sjkim * PARAMETERS: SrcString - The source string to convert 143244971Sjkim * 144244971Sjkim * RETURN: None 145244971Sjkim * 146244971Sjkim * DESCRIPTION: Convert string to uppercase 147244971Sjkim * 148244971Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 149244971Sjkim * 150244971Sjkim ******************************************************************************/ 151244971Sjkim 152244971Sjkimvoid 153244971SjkimAcpiUtStrupr ( 154244971Sjkim char *SrcString) 155244971Sjkim{ 156244971Sjkim char *String; 157244971Sjkim 158244971Sjkim 159244971Sjkim ACPI_FUNCTION_ENTRY (); 160244971Sjkim 161244971Sjkim 162244971Sjkim if (!SrcString) 163244971Sjkim { 164244971Sjkim return; 165244971Sjkim } 166244971Sjkim 167244971Sjkim /* Walk entire string, uppercasing the letters */ 168244971Sjkim 169244971Sjkim for (String = SrcString; *String; String++) 170244971Sjkim { 171244971Sjkim *String = (char) ACPI_TOUPPER (*String); 172244971Sjkim } 173244971Sjkim 174244971Sjkim return; 175244971Sjkim} 176244971Sjkim 177244971Sjkim 178244971Sjkim/******************************************************************************* 179244971Sjkim * 180244971Sjkim * FUNCTION: AcpiUtStrtoul64 181244971Sjkim * 182244971Sjkim * PARAMETERS: String - Null terminated string 183244971Sjkim * Base - Radix of the string: 16 or ACPI_ANY_BASE; 184244971Sjkim * ACPI_ANY_BASE means 'in behalf of ToInteger' 185244971Sjkim * RetInteger - Where the converted integer is returned 186244971Sjkim * 187244971Sjkim * RETURN: Status and Converted value 188244971Sjkim * 189244971Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a 190244971Sjkim * 32-bit or 64-bit conversion, depending on the current mode 191244971Sjkim * of the interpreter. 192244971Sjkim * NOTE: Does not support Octal strings, not needed. 193244971Sjkim * 194244971Sjkim ******************************************************************************/ 195244971Sjkim 196244971SjkimACPI_STATUS 197244971SjkimAcpiUtStrtoul64 ( 198244971Sjkim char *String, 199244971Sjkim UINT32 Base, 200244971Sjkim UINT64 *RetInteger) 201244971Sjkim{ 202244971Sjkim UINT32 ThisDigit = 0; 203244971Sjkim UINT64 ReturnValue = 0; 204244971Sjkim UINT64 Quotient; 205244971Sjkim UINT64 Dividend; 206244971Sjkim UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 207244971Sjkim UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 208244971Sjkim UINT8 ValidDigits = 0; 209244971Sjkim UINT8 SignOf0x = 0; 210244971Sjkim UINT8 Term = 0; 211244971Sjkim 212244971Sjkim 213244971Sjkim ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 214244971Sjkim 215244971Sjkim 216244971Sjkim switch (Base) 217244971Sjkim { 218244971Sjkim case ACPI_ANY_BASE: 219244971Sjkim case 16: 220250838Sjkim 221244971Sjkim break; 222244971Sjkim 223244971Sjkim default: 224250838Sjkim 225244971Sjkim /* Invalid Base */ 226250838Sjkim 227244971Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 228244971Sjkim } 229244971Sjkim 230244971Sjkim if (!String) 231244971Sjkim { 232244971Sjkim goto ErrorExit; 233244971Sjkim } 234244971Sjkim 235244971Sjkim /* Skip over any white space in the buffer */ 236244971Sjkim 237244971Sjkim while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 238244971Sjkim { 239244971Sjkim String++; 240244971Sjkim } 241244971Sjkim 242244971Sjkim if (ToIntegerOp) 243244971Sjkim { 244244971Sjkim /* 245244971Sjkim * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 246244971Sjkim * We need to determine if it is decimal or hexadecimal. 247244971Sjkim */ 248244971Sjkim if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 249244971Sjkim { 250244971Sjkim SignOf0x = 1; 251244971Sjkim Base = 16; 252244971Sjkim 253244971Sjkim /* Skip over the leading '0x' */ 254244971Sjkim String += 2; 255244971Sjkim } 256244971Sjkim else 257244971Sjkim { 258244971Sjkim Base = 10; 259244971Sjkim } 260244971Sjkim } 261244971Sjkim 262244971Sjkim /* Any string left? Check that '0x' is not followed by white space. */ 263244971Sjkim 264244971Sjkim if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 265244971Sjkim { 266244971Sjkim if (ToIntegerOp) 267244971Sjkim { 268244971Sjkim goto ErrorExit; 269244971Sjkim } 270244971Sjkim else 271244971Sjkim { 272244971Sjkim goto AllDone; 273244971Sjkim } 274244971Sjkim } 275244971Sjkim 276244971Sjkim /* 277244971Sjkim * Perform a 32-bit or 64-bit conversion, depending upon the current 278244971Sjkim * execution mode of the interpreter 279244971Sjkim */ 280244971Sjkim Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 281244971Sjkim 282244971Sjkim /* Main loop: convert the string to a 32- or 64-bit integer */ 283244971Sjkim 284244971Sjkim while (*String) 285244971Sjkim { 286244971Sjkim if (ACPI_IS_DIGIT (*String)) 287244971Sjkim { 288244971Sjkim /* Convert ASCII 0-9 to Decimal value */ 289244971Sjkim 290244971Sjkim ThisDigit = ((UINT8) *String) - '0'; 291244971Sjkim } 292244971Sjkim else if (Base == 10) 293244971Sjkim { 294244971Sjkim /* Digit is out of range; possible in ToInteger case only */ 295244971Sjkim 296244971Sjkim Term = 1; 297244971Sjkim } 298244971Sjkim else 299244971Sjkim { 300244971Sjkim ThisDigit = (UINT8) ACPI_TOUPPER (*String); 301244971Sjkim if (ACPI_IS_XDIGIT ((char) ThisDigit)) 302244971Sjkim { 303244971Sjkim /* Convert ASCII Hex char to value */ 304244971Sjkim 305244971Sjkim ThisDigit = ThisDigit - 'A' + 10; 306244971Sjkim } 307244971Sjkim else 308244971Sjkim { 309244971Sjkim Term = 1; 310244971Sjkim } 311244971Sjkim } 312244971Sjkim 313244971Sjkim if (Term) 314244971Sjkim { 315244971Sjkim if (ToIntegerOp) 316244971Sjkim { 317244971Sjkim goto ErrorExit; 318244971Sjkim } 319244971Sjkim else 320244971Sjkim { 321244971Sjkim break; 322244971Sjkim } 323244971Sjkim } 324244971Sjkim else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 325244971Sjkim { 326244971Sjkim /* Skip zeros */ 327244971Sjkim String++; 328244971Sjkim continue; 329244971Sjkim } 330244971Sjkim 331244971Sjkim ValidDigits++; 332244971Sjkim 333244971Sjkim if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 334244971Sjkim { 335244971Sjkim /* 336244971Sjkim * This is ToInteger operation case. 337244971Sjkim * No any restrictions for string-to-integer conversion, 338244971Sjkim * see ACPI spec. 339244971Sjkim */ 340244971Sjkim goto ErrorExit; 341244971Sjkim } 342244971Sjkim 343244971Sjkim /* Divide the digit into the correct position */ 344244971Sjkim 345244971Sjkim (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 346244971Sjkim Base, &Quotient, NULL); 347244971Sjkim 348244971Sjkim if (ReturnValue > Quotient) 349244971Sjkim { 350244971Sjkim if (ToIntegerOp) 351244971Sjkim { 352244971Sjkim goto ErrorExit; 353244971Sjkim } 354244971Sjkim else 355244971Sjkim { 356244971Sjkim break; 357244971Sjkim } 358244971Sjkim } 359244971Sjkim 360244971Sjkim ReturnValue *= Base; 361244971Sjkim ReturnValue += ThisDigit; 362244971Sjkim String++; 363244971Sjkim } 364244971Sjkim 365244971Sjkim /* All done, normal exit */ 366244971Sjkim 367244971SjkimAllDone: 368244971Sjkim 369244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 370244971Sjkim ACPI_FORMAT_UINT64 (ReturnValue))); 371244971Sjkim 372244971Sjkim *RetInteger = ReturnValue; 373244971Sjkim return_ACPI_STATUS (AE_OK); 374244971Sjkim 375244971Sjkim 376244971SjkimErrorExit: 377244971Sjkim /* Base was set/validated above */ 378244971Sjkim 379244971Sjkim if (Base == 10) 380244971Sjkim { 381244971Sjkim return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 382244971Sjkim } 383244971Sjkim else 384244971Sjkim { 385244971Sjkim return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 386244971Sjkim } 387244971Sjkim} 388244971Sjkim 389244971Sjkim 390244971Sjkim/******************************************************************************* 391244971Sjkim * 392244971Sjkim * FUNCTION: AcpiUtPrintString 393244971Sjkim * 394244971Sjkim * PARAMETERS: String - Null terminated ASCII string 395252279Sjkim * MaxLength - Maximum output length. Used to constrain the 396252279Sjkim * length of strings during debug output only. 397244971Sjkim * 398244971Sjkim * RETURN: None 399244971Sjkim * 400244971Sjkim * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 401244971Sjkim * sequences. 402244971Sjkim * 403244971Sjkim ******************************************************************************/ 404244971Sjkim 405244971Sjkimvoid 406244971SjkimAcpiUtPrintString ( 407244971Sjkim char *String, 408252279Sjkim UINT16 MaxLength) 409244971Sjkim{ 410244971Sjkim UINT32 i; 411244971Sjkim 412244971Sjkim 413244971Sjkim if (!String) 414244971Sjkim { 415244971Sjkim AcpiOsPrintf ("<\"NULL STRING PTR\">"); 416244971Sjkim return; 417244971Sjkim } 418244971Sjkim 419244971Sjkim AcpiOsPrintf ("\""); 420281075Sdim for (i = 0; (i < MaxLength) && String[i]; i++) 421244971Sjkim { 422244971Sjkim /* Escape sequences */ 423244971Sjkim 424244971Sjkim switch (String[i]) 425244971Sjkim { 426244971Sjkim case 0x07: 427250838Sjkim 428244971Sjkim AcpiOsPrintf ("\\a"); /* BELL */ 429244971Sjkim break; 430244971Sjkim 431244971Sjkim case 0x08: 432250838Sjkim 433244971Sjkim AcpiOsPrintf ("\\b"); /* BACKSPACE */ 434244971Sjkim break; 435244971Sjkim 436244971Sjkim case 0x0C: 437250838Sjkim 438244971Sjkim AcpiOsPrintf ("\\f"); /* FORMFEED */ 439244971Sjkim break; 440244971Sjkim 441244971Sjkim case 0x0A: 442250838Sjkim 443244971Sjkim AcpiOsPrintf ("\\n"); /* LINEFEED */ 444244971Sjkim break; 445244971Sjkim 446244971Sjkim case 0x0D: 447250838Sjkim 448244971Sjkim AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 449244971Sjkim break; 450244971Sjkim 451244971Sjkim case 0x09: 452250838Sjkim 453244971Sjkim AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 454244971Sjkim break; 455244971Sjkim 456244971Sjkim case 0x0B: 457250838Sjkim 458244971Sjkim AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 459244971Sjkim break; 460244971Sjkim 461244971Sjkim case '\'': /* Single Quote */ 462244971Sjkim case '\"': /* Double Quote */ 463244971Sjkim case '\\': /* Backslash */ 464250838Sjkim 465244971Sjkim AcpiOsPrintf ("\\%c", (int) String[i]); 466244971Sjkim break; 467244971Sjkim 468244971Sjkim default: 469244971Sjkim 470244971Sjkim /* Check for printable character or hex escape */ 471244971Sjkim 472244971Sjkim if (ACPI_IS_PRINT (String[i])) 473244971Sjkim { 474244971Sjkim /* This is a normal character */ 475244971Sjkim 476244971Sjkim AcpiOsPrintf ("%c", (int) String[i]); 477244971Sjkim } 478244971Sjkim else 479244971Sjkim { 480244971Sjkim /* All others will be Hex escapes */ 481244971Sjkim 482244971Sjkim AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 483244971Sjkim } 484244971Sjkim break; 485244971Sjkim } 486244971Sjkim } 487244971Sjkim AcpiOsPrintf ("\""); 488244971Sjkim 489244971Sjkim if (i == MaxLength && String[i]) 490244971Sjkim { 491244971Sjkim AcpiOsPrintf ("..."); 492244971Sjkim } 493244971Sjkim} 494244971Sjkim 495244971Sjkim 496244971Sjkim/******************************************************************************* 497244971Sjkim * 498244971Sjkim * FUNCTION: AcpiUtValidAcpiChar 499244971Sjkim * 500244971Sjkim * PARAMETERS: Char - The character to be examined 501244971Sjkim * Position - Byte position (0-3) 502244971Sjkim * 503244971Sjkim * RETURN: TRUE if the character is valid, FALSE otherwise 504244971Sjkim * 505244971Sjkim * DESCRIPTION: Check for a valid ACPI character. Must be one of: 506244971Sjkim * 1) Upper case alpha 507244971Sjkim * 2) numeric 508244971Sjkim * 3) underscore 509244971Sjkim * 510244971Sjkim * We allow a '!' as the last character because of the ASF! table 511244971Sjkim * 512244971Sjkim ******************************************************************************/ 513244971Sjkim 514244971SjkimBOOLEAN 515244971SjkimAcpiUtValidAcpiChar ( 516244971Sjkim char Character, 517244971Sjkim UINT32 Position) 518244971Sjkim{ 519244971Sjkim 520244971Sjkim if (!((Character >= 'A' && Character <= 'Z') || 521244971Sjkim (Character >= '0' && Character <= '9') || 522244971Sjkim (Character == '_'))) 523244971Sjkim { 524244971Sjkim /* Allow a '!' in the last position */ 525244971Sjkim 526244971Sjkim if (Character == '!' && Position == 3) 527244971Sjkim { 528244971Sjkim return (TRUE); 529244971Sjkim } 530244971Sjkim 531244971Sjkim return (FALSE); 532244971Sjkim } 533244971Sjkim 534244971Sjkim return (TRUE); 535244971Sjkim} 536244971Sjkim 537244971Sjkim 538244971Sjkim/******************************************************************************* 539244971Sjkim * 540244971Sjkim * FUNCTION: AcpiUtValidAcpiName 541244971Sjkim * 542250838Sjkim * PARAMETERS: Name - The name to be examined. Does not have to 543250838Sjkim * be NULL terminated string. 544244971Sjkim * 545244971Sjkim * RETURN: TRUE if the name is valid, FALSE otherwise 546244971Sjkim * 547244971Sjkim * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 548244971Sjkim * 1) Upper case alpha 549244971Sjkim * 2) numeric 550244971Sjkim * 3) underscore 551244971Sjkim * 552244971Sjkim ******************************************************************************/ 553244971Sjkim 554244971SjkimBOOLEAN 555244971SjkimAcpiUtValidAcpiName ( 556250838Sjkim char *Name) 557244971Sjkim{ 558244971Sjkim UINT32 i; 559244971Sjkim 560244971Sjkim 561244971Sjkim ACPI_FUNCTION_ENTRY (); 562244971Sjkim 563244971Sjkim 564244971Sjkim for (i = 0; i < ACPI_NAME_SIZE; i++) 565244971Sjkim { 566250838Sjkim if (!AcpiUtValidAcpiChar (Name[i], i)) 567244971Sjkim { 568244971Sjkim return (FALSE); 569244971Sjkim } 570244971Sjkim } 571244971Sjkim 572244971Sjkim return (TRUE); 573244971Sjkim} 574244971Sjkim 575244971Sjkim 576244971Sjkim/******************************************************************************* 577244971Sjkim * 578244971Sjkim * FUNCTION: AcpiUtRepairName 579244971Sjkim * 580244971Sjkim * PARAMETERS: Name - The ACPI name to be repaired 581244971Sjkim * 582244971Sjkim * RETURN: Repaired version of the name 583244971Sjkim * 584244971Sjkim * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 585244971Sjkim * return the new name. NOTE: the Name parameter must reside in 586244971Sjkim * read/write memory, cannot be a const. 587244971Sjkim * 588244971Sjkim * An ACPI Name must consist of valid ACPI characters. We will repair the name 589244971Sjkim * if necessary because we don't want to abort because of this, but we want 590244971Sjkim * all namespace names to be printable. A warning message is appropriate. 591244971Sjkim * 592244971Sjkim * This issue came up because there are in fact machines that exhibit 593244971Sjkim * this problem, and we want to be able to enable ACPI support for them, 594244971Sjkim * even though there are a few bad names. 595244971Sjkim * 596244971Sjkim ******************************************************************************/ 597244971Sjkim 598244971Sjkimvoid 599244971SjkimAcpiUtRepairName ( 600244971Sjkim char *Name) 601244971Sjkim{ 602244971Sjkim UINT32 i; 603244971Sjkim BOOLEAN FoundBadChar = FALSE; 604244971Sjkim UINT32 OriginalName; 605244971Sjkim 606244971Sjkim 607244971Sjkim ACPI_FUNCTION_NAME (UtRepairName); 608244971Sjkim 609244971Sjkim 610244971Sjkim ACPI_MOVE_NAME (&OriginalName, Name); 611244971Sjkim 612244971Sjkim /* Check each character in the name */ 613244971Sjkim 614244971Sjkim for (i = 0; i < ACPI_NAME_SIZE; i++) 615244971Sjkim { 616244971Sjkim if (AcpiUtValidAcpiChar (Name[i], i)) 617244971Sjkim { 618244971Sjkim continue; 619244971Sjkim } 620244971Sjkim 621244971Sjkim /* 622244971Sjkim * Replace a bad character with something printable, yet technically 623244971Sjkim * still invalid. This prevents any collisions with existing "good" 624244971Sjkim * names in the namespace. 625244971Sjkim */ 626244971Sjkim Name[i] = '*'; 627244971Sjkim FoundBadChar = TRUE; 628244971Sjkim } 629244971Sjkim 630244971Sjkim if (FoundBadChar) 631244971Sjkim { 632244971Sjkim /* Report warning only if in strict mode or debug mode */ 633244971Sjkim 634244971Sjkim if (!AcpiGbl_EnableInterpreterSlack) 635244971Sjkim { 636244971Sjkim ACPI_WARNING ((AE_INFO, 637244971Sjkim "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 638244971Sjkim OriginalName, Name)); 639244971Sjkim } 640244971Sjkim else 641244971Sjkim { 642244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 643244971Sjkim "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 644244971Sjkim OriginalName, Name)); 645244971Sjkim } 646244971Sjkim } 647244971Sjkim} 648244971Sjkim 649244971Sjkim 650244971Sjkim#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 651244971Sjkim/******************************************************************************* 652244971Sjkim * 653244971Sjkim * FUNCTION: UtConvertBackslashes 654244971Sjkim * 655244971Sjkim * PARAMETERS: Pathname - File pathname string to be converted 656244971Sjkim * 657244971Sjkim * RETURN: Modifies the input Pathname 658244971Sjkim * 659244971Sjkim * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 660244971Sjkim * the entire input file pathname string. 661244971Sjkim * 662244971Sjkim ******************************************************************************/ 663244971Sjkim 664244971Sjkimvoid 665244971SjkimUtConvertBackslashes ( 666244971Sjkim char *Pathname) 667244971Sjkim{ 668244971Sjkim 669244971Sjkim if (!Pathname) 670244971Sjkim { 671244971Sjkim return; 672244971Sjkim } 673244971Sjkim 674244971Sjkim while (*Pathname) 675244971Sjkim { 676244971Sjkim if (*Pathname == '\\') 677244971Sjkim { 678244971Sjkim *Pathname = '/'; 679244971Sjkim } 680244971Sjkim 681244971Sjkim Pathname++; 682244971Sjkim } 683244971Sjkim} 684244971Sjkim#endif 685281075Sdim 686281075Sdim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) 687281075Sdim/******************************************************************************* 688281075Sdim * 689281075Sdim * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat 690281075Sdim * 691281075Sdim * PARAMETERS: Adds a "DestSize" parameter to each of the standard string 692281075Sdim * functions. This is the size of the Destination buffer. 693281075Sdim * 694281075Sdim * RETURN: TRUE if the operation would overflow the destination buffer. 695281075Sdim * 696281075Sdim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that 697281075Sdim * the result of the operation will not overflow the output string 698281075Sdim * buffer. 699281075Sdim * 700281075Sdim * NOTE: These functions are typically only helpful for processing 701281075Sdim * user input and command lines. For most ACPICA code, the 702281075Sdim * required buffer length is precisely calculated before buffer 703281075Sdim * allocation, so the use of these functions is unnecessary. 704281075Sdim * 705281075Sdim ******************************************************************************/ 706281075Sdim 707281075SdimBOOLEAN 708281075SdimAcpiUtSafeStrcpy ( 709281075Sdim char *Dest, 710281075Sdim ACPI_SIZE DestSize, 711281075Sdim char *Source) 712281075Sdim{ 713281075Sdim 714281075Sdim if (ACPI_STRLEN (Source) >= DestSize) 715281075Sdim { 716281075Sdim return (TRUE); 717281075Sdim } 718281075Sdim 719281075Sdim ACPI_STRCPY (Dest, Source); 720281075Sdim return (FALSE); 721281075Sdim} 722281075Sdim 723281075SdimBOOLEAN 724281075SdimAcpiUtSafeStrcat ( 725281075Sdim char *Dest, 726281075Sdim ACPI_SIZE DestSize, 727281075Sdim char *Source) 728281075Sdim{ 729281075Sdim 730281075Sdim if ((ACPI_STRLEN (Dest) + ACPI_STRLEN (Source)) >= DestSize) 731281075Sdim { 732281075Sdim return (TRUE); 733281075Sdim } 734281075Sdim 735281075Sdim ACPI_STRCAT (Dest, Source); 736281075Sdim return (FALSE); 737281075Sdim} 738281075Sdim 739281075Sdim#ifndef _KERNEL 740281075SdimBOOLEAN 741281075SdimAcpiUtSafeStrncat ( 742281075Sdim char *Dest, 743281075Sdim ACPI_SIZE DestSize, 744281075Sdim char *Source, 745281075Sdim ACPI_SIZE MaxTransferLength) 746281075Sdim{ 747281075Sdim ACPI_SIZE ActualTransferLength; 748281075Sdim 749281075Sdim 750281075Sdim ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source)); 751281075Sdim 752281075Sdim if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize) 753281075Sdim { 754281075Sdim return (TRUE); 755281075Sdim } 756281075Sdim 757281075Sdim ACPI_STRNCAT (Dest, Source, MaxTransferLength); 758281075Sdim return (FALSE); 759281075Sdim} 760281075Sdim#endif 761281075Sdim 762281075Sdim#endif 763