162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/******************************************************************************* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: utstring - Common functions for strings and characters 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci ******************************************************************************/ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <acpi/acpi.h> 962306a36Sopenharmony_ci#include "accommon.h" 1062306a36Sopenharmony_ci#include "acnamesp.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define _COMPONENT ACPI_UTILITIES 1362306a36Sopenharmony_ciACPI_MODULE_NAME("utstring") 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/******************************************************************************* 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * FUNCTION: acpi_ut_print_string 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * PARAMETERS: string - Null terminated ASCII string 2062306a36Sopenharmony_ci * max_length - Maximum output length. Used to constrain the 2162306a36Sopenharmony_ci * length of strings during debug output only. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * RETURN: None 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 2662306a36Sopenharmony_ci * sequences. 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci ******************************************************************************/ 2962306a36Sopenharmony_civoid acpi_ut_print_string(char *string, u16 max_length) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci u32 i; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci if (!string) { 3462306a36Sopenharmony_ci acpi_os_printf("<\"NULL STRING PTR\">"); 3562306a36Sopenharmony_ci return; 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci acpi_os_printf("\""); 3962306a36Sopenharmony_ci for (i = 0; (i < max_length) && string[i]; i++) { 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci /* Escape sequences */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci switch (string[i]) { 4462306a36Sopenharmony_ci case 0x07: 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci acpi_os_printf("\\a"); /* BELL */ 4762306a36Sopenharmony_ci break; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci case 0x08: 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci acpi_os_printf("\\b"); /* BACKSPACE */ 5262306a36Sopenharmony_ci break; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci case 0x0C: 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci acpi_os_printf("\\f"); /* FORMFEED */ 5762306a36Sopenharmony_ci break; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci case 0x0A: 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci acpi_os_printf("\\n"); /* LINEFEED */ 6262306a36Sopenharmony_ci break; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci case 0x0D: 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci acpi_os_printf("\\r"); /* CARRIAGE RETURN */ 6762306a36Sopenharmony_ci break; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci case 0x09: 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci acpi_os_printf("\\t"); /* HORIZONTAL TAB */ 7262306a36Sopenharmony_ci break; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci case 0x0B: 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci acpi_os_printf("\\v"); /* VERTICAL TAB */ 7762306a36Sopenharmony_ci break; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci case '\'': /* Single Quote */ 8062306a36Sopenharmony_ci case '\"': /* Double Quote */ 8162306a36Sopenharmony_ci case '\\': /* Backslash */ 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci acpi_os_printf("\\%c", (int)string[i]); 8462306a36Sopenharmony_ci break; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci default: 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci /* Check for printable character or hex escape */ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (isprint((int)string[i])) { 9162306a36Sopenharmony_ci /* This is a normal character */ 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci acpi_os_printf("%c", (int)string[i]); 9462306a36Sopenharmony_ci } else { 9562306a36Sopenharmony_ci /* All others will be Hex escapes */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci acpi_os_printf("\\x%2.2X", (s32)string[i]); 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci acpi_os_printf("\""); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if (i == max_length && string[i]) { 10662306a36Sopenharmony_ci acpi_os_printf("..."); 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/******************************************************************************* 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * FUNCTION: acpi_ut_repair_name 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * PARAMETERS: name - The ACPI name to be repaired 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * RETURN: Repaired version of the name 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 11962306a36Sopenharmony_ci * return the new name. NOTE: the Name parameter must reside in 12062306a36Sopenharmony_ci * read/write memory, cannot be a const. 12162306a36Sopenharmony_ci * 12262306a36Sopenharmony_ci * An ACPI Name must consist of valid ACPI characters. We will repair the name 12362306a36Sopenharmony_ci * if necessary because we don't want to abort because of this, but we want 12462306a36Sopenharmony_ci * all namespace names to be printable. A warning message is appropriate. 12562306a36Sopenharmony_ci * 12662306a36Sopenharmony_ci * This issue came up because there are in fact machines that exhibit 12762306a36Sopenharmony_ci * this problem, and we want to be able to enable ACPI support for them, 12862306a36Sopenharmony_ci * even though there are a few bad names. 12962306a36Sopenharmony_ci * 13062306a36Sopenharmony_ci ******************************************************************************/ 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_civoid acpi_ut_repair_name(char *name) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci u32 i; 13562306a36Sopenharmony_ci u8 found_bad_char = FALSE; 13662306a36Sopenharmony_ci u32 original_name; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ACPI_FUNCTION_NAME(ut_repair_name); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci /* 14162306a36Sopenharmony_ci * Special case for the root node. This can happen if we get an 14262306a36Sopenharmony_ci * error during the execution of module-level code. 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci if (ACPI_COMPARE_NAMESEG(name, ACPI_ROOT_PATHNAME)) { 14562306a36Sopenharmony_ci return; 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci ACPI_COPY_NAMESEG(&original_name, &name[0]); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci /* Check each character in the name */ 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci for (i = 0; i < ACPI_NAMESEG_SIZE; i++) { 15362306a36Sopenharmony_ci if (acpi_ut_valid_name_char(name[i], i)) { 15462306a36Sopenharmony_ci continue; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci /* 15862306a36Sopenharmony_ci * Replace a bad character with something printable, yet technically 15962306a36Sopenharmony_ci * "odd". This prevents any collisions with existing "good" 16062306a36Sopenharmony_ci * names in the namespace. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci name[i] = '_'; 16362306a36Sopenharmony_ci found_bad_char = TRUE; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci if (found_bad_char) { 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* Report warning only if in strict mode or debug mode */ 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci if (!acpi_gbl_enable_interpreter_slack) { 17162306a36Sopenharmony_ci ACPI_WARNING((AE_INFO, 17262306a36Sopenharmony_ci "Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]", 17362306a36Sopenharmony_ci original_name, name, &name[0])); 17462306a36Sopenharmony_ci } else { 17562306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_INFO, 17662306a36Sopenharmony_ci "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 17762306a36Sopenharmony_ci original_name, name)); 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 18362306a36Sopenharmony_ci/******************************************************************************* 18462306a36Sopenharmony_ci * 18562306a36Sopenharmony_ci * FUNCTION: ut_convert_backslashes 18662306a36Sopenharmony_ci * 18762306a36Sopenharmony_ci * PARAMETERS: pathname - File pathname string to be converted 18862306a36Sopenharmony_ci * 18962306a36Sopenharmony_ci * RETURN: Modifies the input Pathname 19062306a36Sopenharmony_ci * 19162306a36Sopenharmony_ci * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 19262306a36Sopenharmony_ci * the entire input file pathname string. 19362306a36Sopenharmony_ci * 19462306a36Sopenharmony_ci ******************************************************************************/ 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_civoid ut_convert_backslashes(char *pathname) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (!pathname) { 20062306a36Sopenharmony_ci return; 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci while (*pathname) { 20462306a36Sopenharmony_ci if (*pathname == '\\') { 20562306a36Sopenharmony_ci *pathname = '/'; 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci pathname++; 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci#endif 212