xref: /netbsd-src/sys/external/bsd/acpica/dist/utilities/utstring.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1ff4a156dSchristos /*******************************************************************************
2ff4a156dSchristos  *
3ff4a156dSchristos  * Module Name: utstring - Common functions for strings and characters
4ff4a156dSchristos  *
5ff4a156dSchristos  ******************************************************************************/
6ff4a156dSchristos 
7ff4a156dSchristos /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
9ff4a156dSchristos  * All rights reserved.
10ff4a156dSchristos  *
11ff4a156dSchristos  * Redistribution and use in source and binary forms, with or without
12ff4a156dSchristos  * modification, are permitted provided that the following conditions
13ff4a156dSchristos  * are met:
14ff4a156dSchristos  * 1. Redistributions of source code must retain the above copyright
15ff4a156dSchristos  *    notice, this list of conditions, and the following disclaimer,
16ff4a156dSchristos  *    without modification.
17ff4a156dSchristos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18ff4a156dSchristos  *    substantially similar to the "NO WARRANTY" disclaimer below
19ff4a156dSchristos  *    ("Disclaimer") and any redistribution must be conditioned upon
20ff4a156dSchristos  *    including a substantially similar Disclaimer requirement for further
21ff4a156dSchristos  *    binary redistribution.
22ff4a156dSchristos  * 3. Neither the names of the above-listed copyright holders nor the names
23ff4a156dSchristos  *    of any contributors may be used to endorse or promote products derived
24ff4a156dSchristos  *    from this software without specific prior written permission.
25ff4a156dSchristos  *
26ff4a156dSchristos  * Alternatively, this software may be distributed under the terms of the
27ff4a156dSchristos  * GNU General Public License ("GPL") version 2 as published by the Free
28ff4a156dSchristos  * Software Foundation.
29ff4a156dSchristos  *
30ff4a156dSchristos  * NO WARRANTY
31ff4a156dSchristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32ff4a156dSchristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34ff4a156dSchristos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35ff4a156dSchristos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36ff4a156dSchristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37ff4a156dSchristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38ff4a156dSchristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39ff4a156dSchristos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40ff4a156dSchristos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41ff4a156dSchristos  * POSSIBILITY OF SUCH DAMAGES.
42ff4a156dSchristos  */
43ff4a156dSchristos 
44ff4a156dSchristos #include "acpi.h"
45ff4a156dSchristos #include "accommon.h"
46ff4a156dSchristos #include "acnamesp.h"
47ff4a156dSchristos 
48ff4a156dSchristos 
49ff4a156dSchristos #define _COMPONENT          ACPI_UTILITIES
50ff4a156dSchristos         ACPI_MODULE_NAME    ("utstring")
51ff4a156dSchristos 
52ff4a156dSchristos 
53ff4a156dSchristos /*******************************************************************************
54ff4a156dSchristos  *
55ff4a156dSchristos  * FUNCTION:    AcpiUtPrintString
56ff4a156dSchristos  *
57ff4a156dSchristos  * PARAMETERS:  String          - Null terminated ASCII string
58ff4a156dSchristos  *              MaxLength       - Maximum output length. Used to constrain the
59ff4a156dSchristos  *                                length of strings during debug output only.
60ff4a156dSchristos  *
61ff4a156dSchristos  * RETURN:      None
62ff4a156dSchristos  *
63ff4a156dSchristos  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
64ff4a156dSchristos  *              sequences.
65ff4a156dSchristos  *
66ff4a156dSchristos  ******************************************************************************/
67ff4a156dSchristos 
68ff4a156dSchristos void
AcpiUtPrintString(char * String,UINT16 MaxLength)69ff4a156dSchristos AcpiUtPrintString (
70ff4a156dSchristos     char                    *String,
71ff4a156dSchristos     UINT16                  MaxLength)
72ff4a156dSchristos {
73ff4a156dSchristos     UINT32                  i;
74ff4a156dSchristos 
75ff4a156dSchristos 
76ff4a156dSchristos     if (!String)
77ff4a156dSchristos     {
78ff4a156dSchristos         AcpiOsPrintf ("<\"NULL STRING PTR\">");
79ff4a156dSchristos         return;
80ff4a156dSchristos     }
81ff4a156dSchristos 
82ff4a156dSchristos     AcpiOsPrintf ("\"");
83460301d4Schristos     for (i = 0; (i < MaxLength) && String[i]; i++)
84ff4a156dSchristos     {
85ff4a156dSchristos         /* Escape sequences */
86ff4a156dSchristos 
87ff4a156dSchristos         switch (String[i])
88ff4a156dSchristos         {
89ff4a156dSchristos         case 0x07:
90ff4a156dSchristos 
91ff4a156dSchristos             AcpiOsPrintf ("\\a");       /* BELL */
92ff4a156dSchristos             break;
93ff4a156dSchristos 
94ff4a156dSchristos         case 0x08:
95ff4a156dSchristos 
96ff4a156dSchristos             AcpiOsPrintf ("\\b");       /* BACKSPACE */
97ff4a156dSchristos             break;
98ff4a156dSchristos 
99ff4a156dSchristos         case 0x0C:
100ff4a156dSchristos 
101ff4a156dSchristos             AcpiOsPrintf ("\\f");       /* FORMFEED */
102ff4a156dSchristos             break;
103ff4a156dSchristos 
104ff4a156dSchristos         case 0x0A:
105ff4a156dSchristos 
106ff4a156dSchristos             AcpiOsPrintf ("\\n");       /* LINEFEED */
107ff4a156dSchristos             break;
108ff4a156dSchristos 
109ff4a156dSchristos         case 0x0D:
110ff4a156dSchristos 
111ff4a156dSchristos             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
112ff4a156dSchristos             break;
113ff4a156dSchristos 
114ff4a156dSchristos         case 0x09:
115ff4a156dSchristos 
116ff4a156dSchristos             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
117ff4a156dSchristos             break;
118ff4a156dSchristos 
119ff4a156dSchristos         case 0x0B:
120ff4a156dSchristos 
121ff4a156dSchristos             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
122ff4a156dSchristos             break;
123ff4a156dSchristos 
124ff4a156dSchristos         case '\'':                      /* Single Quote */
125ff4a156dSchristos         case '\"':                      /* Double Quote */
126ff4a156dSchristos         case '\\':                      /* Backslash */
127ff4a156dSchristos 
128ff4a156dSchristos             AcpiOsPrintf ("\\%c", (int) String[i]);
129ff4a156dSchristos             break;
130ff4a156dSchristos 
131ff4a156dSchristos         default:
132ff4a156dSchristos 
133ff4a156dSchristos             /* Check for printable character or hex escape */
134ff4a156dSchristos 
135c72da027Schristos             if (isprint ((int) String[i]))
136ff4a156dSchristos             {
137ff4a156dSchristos                 /* This is a normal character */
138ff4a156dSchristos 
139ff4a156dSchristos                 AcpiOsPrintf ("%c", (int) String[i]);
140ff4a156dSchristos             }
141ff4a156dSchristos             else
142ff4a156dSchristos             {
143ff4a156dSchristos                 /* All others will be Hex escapes */
144ff4a156dSchristos 
145ff4a156dSchristos                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
146ff4a156dSchristos             }
147ff4a156dSchristos             break;
148ff4a156dSchristos         }
149ff4a156dSchristos     }
15071e38f1dSchristos 
151ff4a156dSchristos     AcpiOsPrintf ("\"");
152ff4a156dSchristos 
153ff4a156dSchristos     if (i == MaxLength && String[i])
154ff4a156dSchristos     {
155ff4a156dSchristos         AcpiOsPrintf ("...");
156ff4a156dSchristos     }
157ff4a156dSchristos }
158ff4a156dSchristos 
159ff4a156dSchristos 
160ff4a156dSchristos /*******************************************************************************
161ff4a156dSchristos  *
162ff4a156dSchristos  * FUNCTION:    AcpiUtRepairName
163ff4a156dSchristos  *
164ff4a156dSchristos  * PARAMETERS:  Name            - The ACPI name to be repaired
165ff4a156dSchristos  *
166ff4a156dSchristos  * RETURN:      Repaired version of the name
167ff4a156dSchristos  *
168ff4a156dSchristos  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
169ff4a156dSchristos  *              return the new name. NOTE: the Name parameter must reside in
170ff4a156dSchristos  *              read/write memory, cannot be a const.
171ff4a156dSchristos  *
172ff4a156dSchristos  * An ACPI Name must consist of valid ACPI characters. We will repair the name
173ff4a156dSchristos  * if necessary because we don't want to abort because of this, but we want
174ff4a156dSchristos  * all namespace names to be printable. A warning message is appropriate.
175ff4a156dSchristos  *
176ff4a156dSchristos  * This issue came up because there are in fact machines that exhibit
177ff4a156dSchristos  * this problem, and we want to be able to enable ACPI support for them,
178ff4a156dSchristos  * even though there are a few bad names.
179ff4a156dSchristos  *
180ff4a156dSchristos  ******************************************************************************/
181ff4a156dSchristos 
182ff4a156dSchristos void
AcpiUtRepairName(char * Name)183ff4a156dSchristos AcpiUtRepairName (
184ff4a156dSchristos     char                    *Name)
185ff4a156dSchristos {
186ff4a156dSchristos     UINT32                  i;
187ff4a156dSchristos     BOOLEAN                 FoundBadChar = FALSE;
188ff4a156dSchristos     UINT32                  OriginalName;
189ff4a156dSchristos 
190ff4a156dSchristos 
191ff4a156dSchristos     ACPI_FUNCTION_NAME (UtRepairName);
192ff4a156dSchristos 
193ff4a156dSchristos 
19471e38f1dSchristos     /*
19571e38f1dSchristos      * Special case for the root node. This can happen if we get an
19671e38f1dSchristos      * error during the execution of module-level code.
19771e38f1dSchristos      */
19894783addSchristos     if (ACPI_COMPARE_NAMESEG (Name, ACPI_ROOT_PATHNAME))
19971e38f1dSchristos     {
20071e38f1dSchristos         return;
20171e38f1dSchristos     }
20271e38f1dSchristos 
20382065f3bSchristos     ACPI_COPY_NAMESEG (&OriginalName, &Name[0]);
204ff4a156dSchristos 
205ff4a156dSchristos     /* Check each character in the name */
206ff4a156dSchristos 
20794783addSchristos     for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
208ff4a156dSchristos     {
209cfbb7280Schristos         if (AcpiUtValidNameChar (Name[i], i))
210ff4a156dSchristos         {
211ff4a156dSchristos             continue;
212ff4a156dSchristos         }
213ff4a156dSchristos 
214ff4a156dSchristos         /*
215ff4a156dSchristos          * Replace a bad character with something printable, yet technically
21682065f3bSchristos          * "odd". This prevents any collisions with existing "good"
217ff4a156dSchristos          * names in the namespace.
218ff4a156dSchristos          */
21982065f3bSchristos         Name[i] = '_';
220ff4a156dSchristos         FoundBadChar = TRUE;
221ff4a156dSchristos     }
222ff4a156dSchristos 
223ff4a156dSchristos     if (FoundBadChar)
224ff4a156dSchristos     {
225ff4a156dSchristos         /* Report warning only if in strict mode or debug mode */
226ff4a156dSchristos 
227ff4a156dSchristos         if (!AcpiGbl_EnableInterpreterSlack)
228ff4a156dSchristos         {
229ff4a156dSchristos             ACPI_WARNING ((AE_INFO,
23082065f3bSchristos                 "Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]",
23182065f3bSchristos                 OriginalName, Name, &Name[0]));
232ff4a156dSchristos         }
233ff4a156dSchristos         else
234ff4a156dSchristos         {
235ff4a156dSchristos             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
236ff4a156dSchristos                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
237ff4a156dSchristos                 OriginalName, Name));
238ff4a156dSchristos         }
239ff4a156dSchristos     }
240ff4a156dSchristos }
241ff4a156dSchristos 
242ff4a156dSchristos 
243ff4a156dSchristos #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
244ff4a156dSchristos /*******************************************************************************
245ff4a156dSchristos  *
246ff4a156dSchristos  * FUNCTION:    UtConvertBackslashes
247ff4a156dSchristos  *
248ff4a156dSchristos  * PARAMETERS:  Pathname        - File pathname string to be converted
249ff4a156dSchristos  *
250ff4a156dSchristos  * RETURN:      Modifies the input Pathname
251ff4a156dSchristos  *
252ff4a156dSchristos  * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
253ff4a156dSchristos  *              the entire input file pathname string.
254ff4a156dSchristos  *
255ff4a156dSchristos  ******************************************************************************/
256ff4a156dSchristos 
257ff4a156dSchristos void
UtConvertBackslashes(char * Pathname)258ff4a156dSchristos UtConvertBackslashes (
259ff4a156dSchristos     char                    *Pathname)
260ff4a156dSchristos {
261ff4a156dSchristos 
262ff4a156dSchristos     if (!Pathname)
263ff4a156dSchristos     {
264ff4a156dSchristos         return;
265ff4a156dSchristos     }
266ff4a156dSchristos 
267ff4a156dSchristos     while (*Pathname)
268ff4a156dSchristos     {
269ff4a156dSchristos         if (*Pathname == '\\')
270ff4a156dSchristos         {
271ff4a156dSchristos             *Pathname = '/';
272ff4a156dSchristos         }
273ff4a156dSchristos 
274ff4a156dSchristos         Pathname++;
275ff4a156dSchristos     }
276ff4a156dSchristos }
277ff4a156dSchristos #endif
278