1 | /******************************************************************************* |
2 | * |
3 | * Module Name: utstring - Common functions for strings and characters |
4 | * |
5 | ******************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, Intel Corp. |
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.h" |
45 | #include "accommon.h" |
46 | #include "acnamesp.h" |
47 | |
48 | |
49 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME ("utstring" ) |
51 | |
52 | |
53 | /******************************************************************************* |
54 | * |
55 | * FUNCTION: AcpiUtPrintString |
56 | * |
57 | * PARAMETERS: String - Null terminated ASCII string |
58 | * MaxLength - Maximum output length. Used to constrain the |
59 | * length of strings during debug output only. |
60 | * |
61 | * RETURN: None |
62 | * |
63 | * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape |
64 | * sequences. |
65 | * |
66 | ******************************************************************************/ |
67 | |
68 | void |
69 | AcpiUtPrintString ( |
70 | char *String, |
71 | UINT16 MaxLength) |
72 | { |
73 | UINT32 i; |
74 | |
75 | |
76 | if (!String) |
77 | { |
78 | AcpiOsPrintf ("<\"NULL STRING PTR\">" ); |
79 | return; |
80 | } |
81 | |
82 | AcpiOsPrintf ("\"" ); |
83 | for (i = 0; (i < MaxLength) && String[i]; i++) |
84 | { |
85 | /* Escape sequences */ |
86 | |
87 | switch (String[i]) |
88 | { |
89 | case 0x07: |
90 | |
91 | AcpiOsPrintf ("\\a" ); /* BELL */ |
92 | break; |
93 | |
94 | case 0x08: |
95 | |
96 | AcpiOsPrintf ("\\b" ); /* BACKSPACE */ |
97 | break; |
98 | |
99 | case 0x0C: |
100 | |
101 | AcpiOsPrintf ("\\f" ); /* FORMFEED */ |
102 | break; |
103 | |
104 | case 0x0A: |
105 | |
106 | AcpiOsPrintf ("\\n" ); /* LINEFEED */ |
107 | break; |
108 | |
109 | case 0x0D: |
110 | |
111 | AcpiOsPrintf ("\\r" ); /* CARRIAGE RETURN*/ |
112 | break; |
113 | |
114 | case 0x09: |
115 | |
116 | AcpiOsPrintf ("\\t" ); /* HORIZONTAL TAB */ |
117 | break; |
118 | |
119 | case 0x0B: |
120 | |
121 | AcpiOsPrintf ("\\v" ); /* VERTICAL TAB */ |
122 | break; |
123 | |
124 | case '\'': /* Single Quote */ |
125 | case '\"': /* Double Quote */ |
126 | case '\\': /* Backslash */ |
127 | |
128 | AcpiOsPrintf ("\\%c" , (int) String[i]); |
129 | break; |
130 | |
131 | default: |
132 | |
133 | /* Check for printable character or hex escape */ |
134 | |
135 | if (isprint ((int) String[i])) |
136 | { |
137 | /* This is a normal character */ |
138 | |
139 | AcpiOsPrintf ("%c" , (int) String[i]); |
140 | } |
141 | else |
142 | { |
143 | /* All others will be Hex escapes */ |
144 | |
145 | AcpiOsPrintf ("\\x%2.2X" , (INT32) String[i]); |
146 | } |
147 | break; |
148 | } |
149 | } |
150 | |
151 | AcpiOsPrintf ("\"" ); |
152 | |
153 | if (i == MaxLength && String[i]) |
154 | { |
155 | AcpiOsPrintf ("..." ); |
156 | } |
157 | } |
158 | |
159 | |
160 | /******************************************************************************* |
161 | * |
162 | * FUNCTION: AcpiUtRepairName |
163 | * |
164 | * PARAMETERS: Name - The ACPI name to be repaired |
165 | * |
166 | * RETURN: Repaired version of the name |
167 | * |
168 | * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and |
169 | * return the new name. NOTE: the Name parameter must reside in |
170 | * read/write memory, cannot be a const. |
171 | * |
172 | * An ACPI Name must consist of valid ACPI characters. We will repair the name |
173 | * if necessary because we don't want to abort because of this, but we want |
174 | * all namespace names to be printable. A warning message is appropriate. |
175 | * |
176 | * This issue came up because there are in fact machines that exhibit |
177 | * this problem, and we want to be able to enable ACPI support for them, |
178 | * even though there are a few bad names. |
179 | * |
180 | ******************************************************************************/ |
181 | |
182 | void |
183 | AcpiUtRepairName ( |
184 | char *Name) |
185 | { |
186 | UINT32 i; |
187 | BOOLEAN FoundBadChar = FALSE; |
188 | UINT32 OriginalName; |
189 | |
190 | |
191 | ACPI_FUNCTION_NAME (UtRepairName); |
192 | |
193 | |
194 | /* |
195 | * Special case for the root node. This can happen if we get an |
196 | * error during the execution of module-level code. |
197 | */ |
198 | if (ACPI_COMPARE_NAME (Name, "\\___" )) |
199 | { |
200 | return; |
201 | } |
202 | |
203 | ACPI_MOVE_NAME (&OriginalName, Name); |
204 | |
205 | /* Check each character in the name */ |
206 | |
207 | for (i = 0; i < ACPI_NAME_SIZE; i++) |
208 | { |
209 | if (AcpiUtValidNameChar (Name[i], i)) |
210 | { |
211 | continue; |
212 | } |
213 | |
214 | /* |
215 | * Replace a bad character with something printable, yet technically |
216 | * still invalid. This prevents any collisions with existing "good" |
217 | * names in the namespace. |
218 | */ |
219 | Name[i] = '*'; |
220 | FoundBadChar = TRUE; |
221 | } |
222 | |
223 | if (FoundBadChar) |
224 | { |
225 | /* Report warning only if in strict mode or debug mode */ |
226 | |
227 | if (!AcpiGbl_EnableInterpreterSlack) |
228 | { |
229 | ACPI_WARNING ((AE_INFO, |
230 | "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]" , |
231 | OriginalName, Name)); |
232 | } |
233 | else |
234 | { |
235 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
236 | "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]" , |
237 | OriginalName, Name)); |
238 | } |
239 | } |
240 | } |
241 | |
242 | |
243 | #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP |
244 | /******************************************************************************* |
245 | * |
246 | * FUNCTION: UtConvertBackslashes |
247 | * |
248 | * PARAMETERS: Pathname - File pathname string to be converted |
249 | * |
250 | * RETURN: Modifies the input Pathname |
251 | * |
252 | * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within |
253 | * the entire input file pathname string. |
254 | * |
255 | ******************************************************************************/ |
256 | |
257 | void |
258 | UtConvertBackslashes ( |
259 | char *Pathname) |
260 | { |
261 | |
262 | if (!Pathname) |
263 | { |
264 | return; |
265 | } |
266 | |
267 | while (*Pathname) |
268 | { |
269 | if (*Pathname == '\\') |
270 | { |
271 | *Pathname = '/'; |
272 | } |
273 | |
274 | Pathname++; |
275 | } |
276 | } |
277 | #endif |
278 | |