xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/utstring.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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