Commit | Line | Data |
---|---|---|
42f8fb75 BM |
1 | /******************************************************************************* |
2 | * | |
3 | * Module Name: utstring - Common functions for strings and characters | |
4 | * | |
5 | ******************************************************************************/ | |
6 | ||
7 | /* | |
c8100dc4 | 8 | * Copyright (C) 2000 - 2016, Intel Corp. |
42f8fb75 BM |
9 | * All rights reserved. |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions, and the following disclaimer, | |
16 | * without modification. | |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | |
20 | * including a substantially similar Disclaimer requirement for further | |
21 | * binary redistribution. | |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | |
23 | * of any contributors may be used to endorse or promote products derived | |
24 | * from this software without specific prior written permission. | |
25 | * | |
26 | * Alternatively, this software may be distributed under the terms of the | |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | |
28 | * Software Foundation. | |
29 | * | |
30 | * NO WARRANTY | |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
41 | * POSSIBILITY OF SUCH DAMAGES. | |
42 | */ | |
43 | ||
44 | #include <acpi/acpi.h> | |
45 | #include "accommon.h" | |
46 | #include "acnamesp.h" | |
47 | ||
48 | #define _COMPONENT ACPI_UTILITIES | |
49 | ACPI_MODULE_NAME("utstring") | |
50 | ||
42f8fb75 BM |
51 | /******************************************************************************* |
52 | * | |
53 | * FUNCTION: acpi_ut_print_string | |
54 | * | |
55 | * PARAMETERS: string - Null terminated ASCII string | |
0fb3adf8 BM |
56 | * max_length - Maximum output length. Used to constrain the |
57 | * length of strings during debug output only. | |
42f8fb75 BM |
58 | * |
59 | * RETURN: None | |
60 | * | |
61 | * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape | |
62 | * sequences. | |
63 | * | |
64 | ******************************************************************************/ | |
0fb3adf8 | 65 | void acpi_ut_print_string(char *string, u16 max_length) |
42f8fb75 BM |
66 | { |
67 | u32 i; | |
68 | ||
69 | if (!string) { | |
70 | acpi_os_printf("<\"NULL STRING PTR\">"); | |
71 | return; | |
72 | } | |
73 | ||
74 | acpi_os_printf("\""); | |
5d42b0fa | 75 | for (i = 0; (i < max_length) && string[i]; i++) { |
42f8fb75 BM |
76 | |
77 | /* Escape sequences */ | |
78 | ||
79 | switch (string[i]) { | |
80 | case 0x07: | |
1d1ea1b7 | 81 | |
42f8fb75 BM |
82 | acpi_os_printf("\\a"); /* BELL */ |
83 | break; | |
84 | ||
85 | case 0x08: | |
1d1ea1b7 | 86 | |
42f8fb75 BM |
87 | acpi_os_printf("\\b"); /* BACKSPACE */ |
88 | break; | |
89 | ||
90 | case 0x0C: | |
1d1ea1b7 | 91 | |
42f8fb75 BM |
92 | acpi_os_printf("\\f"); /* FORMFEED */ |
93 | break; | |
94 | ||
95 | case 0x0A: | |
1d1ea1b7 | 96 | |
42f8fb75 BM |
97 | acpi_os_printf("\\n"); /* LINEFEED */ |
98 | break; | |
99 | ||
100 | case 0x0D: | |
1d1ea1b7 | 101 | |
42f8fb75 BM |
102 | acpi_os_printf("\\r"); /* CARRIAGE RETURN */ |
103 | break; | |
104 | ||
105 | case 0x09: | |
1d1ea1b7 | 106 | |
42f8fb75 BM |
107 | acpi_os_printf("\\t"); /* HORIZONTAL TAB */ |
108 | break; | |
109 | ||
110 | case 0x0B: | |
1d1ea1b7 | 111 | |
42f8fb75 BM |
112 | acpi_os_printf("\\v"); /* VERTICAL TAB */ |
113 | break; | |
114 | ||
115 | case '\'': /* Single Quote */ | |
116 | case '\"': /* Double Quote */ | |
117 | case '\\': /* Backslash */ | |
1d1ea1b7 | 118 | |
42f8fb75 BM |
119 | acpi_os_printf("\\%c", (int)string[i]); |
120 | break; | |
121 | ||
122 | default: | |
123 | ||
124 | /* Check for printable character or hex escape */ | |
125 | ||
4fa4616e | 126 | if (isprint((int)string[i])) { |
42f8fb75 BM |
127 | /* This is a normal character */ |
128 | ||
129 | acpi_os_printf("%c", (int)string[i]); | |
130 | } else { | |
131 | /* All others will be Hex escapes */ | |
132 | ||
133 | acpi_os_printf("\\x%2.2X", (s32) string[i]); | |
134 | } | |
135 | break; | |
136 | } | |
137 | } | |
1fad8738 | 138 | |
42f8fb75 BM |
139 | acpi_os_printf("\""); |
140 | ||
141 | if (i == max_length && string[i]) { | |
142 | acpi_os_printf("..."); | |
143 | } | |
144 | } | |
145 | ||
146 | /******************************************************************************* | |
147 | * | |
148 | * FUNCTION: acpi_ut_valid_acpi_char | |
149 | * | |
150 | * PARAMETERS: char - The character to be examined | |
151 | * position - Byte position (0-3) | |
152 | * | |
153 | * RETURN: TRUE if the character is valid, FALSE otherwise | |
154 | * | |
155 | * DESCRIPTION: Check for a valid ACPI character. Must be one of: | |
156 | * 1) Upper case alpha | |
157 | * 2) numeric | |
158 | * 3) underscore | |
159 | * | |
160 | * We allow a '!' as the last character because of the ASF! table | |
161 | * | |
162 | ******************************************************************************/ | |
163 | ||
164 | u8 acpi_ut_valid_acpi_char(char character, u32 position) | |
165 | { | |
166 | ||
167 | if (!((character >= 'A' && character <= 'Z') || | |
168 | (character >= '0' && character <= '9') || (character == '_'))) { | |
169 | ||
170 | /* Allow a '!' in the last position */ | |
171 | ||
172 | if (character == '!' && position == 3) { | |
173 | return (TRUE); | |
174 | } | |
175 | ||
176 | return (FALSE); | |
177 | } | |
178 | ||
179 | return (TRUE); | |
180 | } | |
181 | ||
182 | /******************************************************************************* | |
183 | * | |
184 | * FUNCTION: acpi_ut_valid_acpi_name | |
185 | * | |
de8e7db7 BM |
186 | * PARAMETERS: name - The name to be examined. Does not have to |
187 | * be NULL terminated string. | |
42f8fb75 BM |
188 | * |
189 | * RETURN: TRUE if the name is valid, FALSE otherwise | |
190 | * | |
191 | * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: | |
192 | * 1) Upper case alpha | |
193 | * 2) numeric | |
194 | * 3) underscore | |
195 | * | |
196 | ******************************************************************************/ | |
197 | ||
de8e7db7 | 198 | u8 acpi_ut_valid_acpi_name(char *name) |
42f8fb75 BM |
199 | { |
200 | u32 i; | |
201 | ||
202 | ACPI_FUNCTION_ENTRY(); | |
203 | ||
204 | for (i = 0; i < ACPI_NAME_SIZE; i++) { | |
de8e7db7 | 205 | if (!acpi_ut_valid_acpi_char(name[i], i)) { |
42f8fb75 BM |
206 | return (FALSE); |
207 | } | |
208 | } | |
209 | ||
210 | return (TRUE); | |
211 | } | |
212 | ||
213 | /******************************************************************************* | |
214 | * | |
215 | * FUNCTION: acpi_ut_repair_name | |
216 | * | |
217 | * PARAMETERS: name - The ACPI name to be repaired | |
218 | * | |
219 | * RETURN: Repaired version of the name | |
220 | * | |
221 | * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and | |
222 | * return the new name. NOTE: the Name parameter must reside in | |
223 | * read/write memory, cannot be a const. | |
224 | * | |
225 | * An ACPI Name must consist of valid ACPI characters. We will repair the name | |
226 | * if necessary because we don't want to abort because of this, but we want | |
227 | * all namespace names to be printable. A warning message is appropriate. | |
228 | * | |
229 | * This issue came up because there are in fact machines that exhibit | |
230 | * this problem, and we want to be able to enable ACPI support for them, | |
231 | * even though there are a few bad names. | |
232 | * | |
233 | ******************************************************************************/ | |
234 | ||
235 | void acpi_ut_repair_name(char *name) | |
236 | { | |
237 | u32 i; | |
238 | u8 found_bad_char = FALSE; | |
239 | u32 original_name; | |
240 | ||
241 | ACPI_FUNCTION_NAME(ut_repair_name); | |
242 | ||
22472353 BM |
243 | /* |
244 | * Special case for the root node. This can happen if we get an | |
245 | * error during the execution of module-level code. | |
246 | */ | |
247 | if (ACPI_COMPARE_NAME(name, "\\___")) { | |
248 | return; | |
249 | } | |
250 | ||
42f8fb75 BM |
251 | ACPI_MOVE_NAME(&original_name, name); |
252 | ||
253 | /* Check each character in the name */ | |
254 | ||
255 | for (i = 0; i < ACPI_NAME_SIZE; i++) { | |
256 | if (acpi_ut_valid_acpi_char(name[i], i)) { | |
257 | continue; | |
258 | } | |
259 | ||
260 | /* | |
261 | * Replace a bad character with something printable, yet technically | |
262 | * still invalid. This prevents any collisions with existing "good" | |
263 | * names in the namespace. | |
264 | */ | |
265 | name[i] = '*'; | |
266 | found_bad_char = TRUE; | |
267 | } | |
268 | ||
269 | if (found_bad_char) { | |
270 | ||
271 | /* Report warning only if in strict mode or debug mode */ | |
272 | ||
273 | if (!acpi_gbl_enable_interpreter_slack) { | |
274 | ACPI_WARNING((AE_INFO, | |
275 | "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", | |
276 | original_name, name)); | |
277 | } else { | |
278 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | |
279 | "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", | |
280 | original_name, name)); | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
285 | #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP | |
286 | /******************************************************************************* | |
287 | * | |
288 | * FUNCTION: ut_convert_backslashes | |
289 | * | |
290 | * PARAMETERS: pathname - File pathname string to be converted | |
291 | * | |
292 | * RETURN: Modifies the input Pathname | |
293 | * | |
294 | * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within | |
295 | * the entire input file pathname string. | |
296 | * | |
297 | ******************************************************************************/ | |
298 | ||
299 | void ut_convert_backslashes(char *pathname) | |
300 | { | |
301 | ||
302 | if (!pathname) { | |
303 | return; | |
304 | } | |
305 | ||
306 | while (*pathname) { | |
307 | if (*pathname == '\\') { | |
308 | *pathname = '/'; | |
309 | } | |
310 | ||
311 | pathname++; | |
312 | } | |
313 | } | |
314 | #endif |