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