1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 3 * 4 * Module Name: utstring - Common functions for strings and characters 5 * 6 ******************************************************************************/ 7 8 #include <acpi/acpi.h> 9 #include "accommon.h" 10 #include "acnamesp.h" 11 12 #define _COMPONENT ACPI_UTILITIES 13 ACPI_MODULE_NAME("utstring") 14 15 /******************************************************************************* 16 * 17 * FUNCTION: acpi_ut_print_string 18 * 19 * PARAMETERS: string - Null terminated ASCII string 20 * max_length - Maximum output length. Used to constrain the 21 * length of strings during debug output only. 22 * 23 * RETURN: None 24 * 25 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 26 * sequences. 27 * 28 ******************************************************************************/ 29 void acpi_ut_print_string(char *string, u16 max_length) 30 { 31 u32 i; 32 33 if (!string) { 34 acpi_os_printf("<\"NULL STRING PTR\">"); 35 return; 36 } 37 38 acpi_os_printf("\""); 39 for (i = 0; (i < max_length) && string[i]; i++) { 40 41 /* Escape sequences */ 42 43 switch (string[i]) { 44 case 0x07: 45 46 acpi_os_printf("\\a"); /* BELL */ 47 break; 48 49 case 0x08: 50 51 acpi_os_printf("\\b"); /* BACKSPACE */ 52 break; 53 54 case 0x0C: 55 56 acpi_os_printf("\\f"); /* FORMFEED */ 57 break; 58 59 case 0x0A: 60 61 acpi_os_printf("\\n"); /* LINEFEED */ 62 break; 63 64 case 0x0D: 65 66 acpi_os_printf("\\r"); /* CARRIAGE RETURN */ 67 break; 68 69 case 0x09: 70 71 acpi_os_printf("\\t"); /* HORIZONTAL TAB */ 72 break; 73 74 case 0x0B: 75 76 acpi_os_printf("\\v"); /* VERTICAL TAB */ 77 break; 78 79 case '\'': /* Single Quote */ 80 case '\"': /* Double Quote */ 81 case '\\': /* Backslash */ 82 83 acpi_os_printf("\\%c", (int)string[i]); 84 break; 85 86 default: 87 88 /* Check for printable character or hex escape */ 89 90 if (isprint((int)string[i])) { 91 /* This is a normal character */ 92 93 acpi_os_printf("%c", (int)string[i]); 94 } else { 95 /* All others will be Hex escapes */ 96 97 acpi_os_printf("\\x%2.2X", (s32)string[i]); 98 } 99 break; 100 } 101 } 102 103 acpi_os_printf("\""); 104 105 if (i == max_length && string[i]) { 106 acpi_os_printf("..."); 107 } 108 } 109 110 /******************************************************************************* 111 * 112 * FUNCTION: acpi_ut_repair_name 113 * 114 * PARAMETERS: name - The ACPI name to be repaired 115 * 116 * RETURN: Repaired version of the name 117 * 118 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 119 * return the new name. NOTE: the Name parameter must reside in 120 * read/write memory, cannot be a const. 121 * 122 * An ACPI Name must consist of valid ACPI characters. We will repair the name 123 * if necessary because we don't want to abort because of this, but we want 124 * all namespace names to be printable. A warning message is appropriate. 125 * 126 * This issue came up because there are in fact machines that exhibit 127 * this problem, and we want to be able to enable ACPI support for them, 128 * even though there are a few bad names. 129 * 130 ******************************************************************************/ 131 132 void acpi_ut_repair_name(char *name) 133 { 134 u32 i; 135 u8 found_bad_char = FALSE; 136 u32 original_name; 137 138 ACPI_FUNCTION_NAME(ut_repair_name); 139 140 /* 141 * Special case for the root node. This can happen if we get an 142 * error during the execution of module-level code. 143 */ 144 if (ACPI_COMPARE_NAMESEG(name, ACPI_ROOT_PATHNAME)) { 145 return; 146 } 147 148 ACPI_COPY_NAMESEG(&original_name, name); 149 150 /* Check each character in the name */ 151 152 for (i = 0; i < ACPI_NAMESEG_SIZE; i++) { 153 if (acpi_ut_valid_name_char(name[i], i)) { 154 continue; 155 } 156 157 /* 158 * Replace a bad character with something printable, yet technically 159 * still invalid. This prevents any collisions with existing "good" 160 * names in the namespace. 161 */ 162 name[i] = '*'; 163 found_bad_char = TRUE; 164 } 165 166 if (found_bad_char) { 167 168 /* Report warning only if in strict mode or debug mode */ 169 170 if (!acpi_gbl_enable_interpreter_slack) { 171 ACPI_WARNING((AE_INFO, 172 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 173 original_name, name)); 174 } else { 175 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 176 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 177 original_name, name)); 178 } 179 } 180 } 181 182 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 183 /******************************************************************************* 184 * 185 * FUNCTION: ut_convert_backslashes 186 * 187 * PARAMETERS: pathname - File pathname string to be converted 188 * 189 * RETURN: Modifies the input Pathname 190 * 191 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 192 * the entire input file pathname string. 193 * 194 ******************************************************************************/ 195 196 void ut_convert_backslashes(char *pathname) 197 { 198 199 if (!pathname) { 200 return; 201 } 202 203 while (*pathname) { 204 if (*pathname == '\\') { 205 *pathname = '/'; 206 } 207 208 pathname++; 209 } 210 } 211 #endif 212