1244971Sjkim/*******************************************************************************
2244971Sjkim *
3244971Sjkim * Module Name: utstring - Common functions for strings and characters
4244971Sjkim *
5244971Sjkim ******************************************************************************/
6244971Sjkim
7244971Sjkim/*
8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp.
9244971Sjkim * All rights reserved.
10244971Sjkim *
11244971Sjkim * Redistribution and use in source and binary forms, with or without
12244971Sjkim * modification, are permitted provided that the following conditions
13244971Sjkim * are met:
14244971Sjkim * 1. Redistributions of source code must retain the above copyright
15244971Sjkim *    notice, this list of conditions, and the following disclaimer,
16244971Sjkim *    without modification.
17244971Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18244971Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19244971Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20244971Sjkim *    including a substantially similar Disclaimer requirement for further
21244971Sjkim *    binary redistribution.
22244971Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23244971Sjkim *    of any contributors may be used to endorse or promote products derived
24244971Sjkim *    from this software without specific prior written permission.
25244971Sjkim *
26244971Sjkim * Alternatively, this software may be distributed under the terms of the
27244971Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28244971Sjkim * Software Foundation.
29244971Sjkim *
30244971Sjkim * NO WARRANTY
31244971Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32244971Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33244971Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34244971Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35244971Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36244971Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37244971Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38244971Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39244971Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40244971Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41244971Sjkim * POSSIBILITY OF SUCH DAMAGES.
42244971Sjkim */
43244971Sjkim
44245582Sjkim#include <contrib/dev/acpica/include/acpi.h>
45245582Sjkim#include <contrib/dev/acpica/include/accommon.h>
46245582Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
47244971Sjkim
48244971Sjkim
49244971Sjkim#define _COMPONENT          ACPI_UTILITIES
50244971Sjkim        ACPI_MODULE_NAME    ("utstring")
51244971Sjkim
52244971Sjkim
53244971Sjkim/*
54244971Sjkim * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
55244971Sjkim * version of strtoul.
56244971Sjkim */
57244971Sjkim
58244971Sjkim#ifdef ACPI_ASL_COMPILER
59244971Sjkim/*******************************************************************************
60244971Sjkim *
61244971Sjkim * FUNCTION:    AcpiUtStrlwr (strlwr)
62244971Sjkim *
63244971Sjkim * PARAMETERS:  SrcString       - The source string to convert
64244971Sjkim *
65244971Sjkim * RETURN:      None
66244971Sjkim *
67244971Sjkim * DESCRIPTION: Convert string to lowercase
68244971Sjkim *
69244971Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
70244971Sjkim *
71244971Sjkim ******************************************************************************/
72244971Sjkim
73244971Sjkimvoid
74244971SjkimAcpiUtStrlwr (
75244971Sjkim    char                    *SrcString)
76244971Sjkim{
77244971Sjkim    char                    *String;
78244971Sjkim
79244971Sjkim
80244971Sjkim    ACPI_FUNCTION_ENTRY ();
81244971Sjkim
82244971Sjkim
83244971Sjkim    if (!SrcString)
84244971Sjkim    {
85244971Sjkim        return;
86244971Sjkim    }
87244971Sjkim
88244971Sjkim    /* Walk entire string, lowercasing the letters */
89244971Sjkim
90244971Sjkim    for (String = SrcString; *String; String++)
91244971Sjkim    {
92244971Sjkim        *String = (char) ACPI_TOLOWER (*String);
93244971Sjkim    }
94244971Sjkim
95244971Sjkim    return;
96244971Sjkim}
97244971Sjkim
98244971Sjkim
99244971Sjkim/******************************************************************************
100244971Sjkim *
101244971Sjkim * FUNCTION:    AcpiUtStricmp (stricmp)
102244971Sjkim *
103244971Sjkim * PARAMETERS:  String1             - first string to compare
104244971Sjkim *              String2             - second string to compare
105244971Sjkim *
106244971Sjkim * RETURN:      int that signifies string relationship. Zero means strings
107244971Sjkim *              are equal.
108244971Sjkim *
109244971Sjkim * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
110244971Sjkim *              strings with no case sensitivity)
111244971Sjkim *
112244971Sjkim ******************************************************************************/
113244971Sjkim
114244971Sjkimint
115244971SjkimAcpiUtStricmp (
116244971Sjkim    char                    *String1,
117244971Sjkim    char                    *String2)
118244971Sjkim{
119244971Sjkim    int                     c1;
120244971Sjkim    int                     c2;
121244971Sjkim
122244971Sjkim
123244971Sjkim    do
124244971Sjkim    {
125244971Sjkim        c1 = tolower ((int) *String1);
126244971Sjkim        c2 = tolower ((int) *String2);
127244971Sjkim
128244971Sjkim        String1++;
129244971Sjkim        String2++;
130244971Sjkim    }
131244971Sjkim    while ((c1 == c2) && (c1));
132244971Sjkim
133244971Sjkim    return (c1 - c2);
134244971Sjkim}
135244971Sjkim#endif
136244971Sjkim
137244971Sjkim
138244971Sjkim/*******************************************************************************
139244971Sjkim *
140244971Sjkim * FUNCTION:    AcpiUtStrupr (strupr)
141244971Sjkim *
142244971Sjkim * PARAMETERS:  SrcString       - The source string to convert
143244971Sjkim *
144244971Sjkim * RETURN:      None
145244971Sjkim *
146244971Sjkim * DESCRIPTION: Convert string to uppercase
147244971Sjkim *
148244971Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
149244971Sjkim *
150244971Sjkim ******************************************************************************/
151244971Sjkim
152244971Sjkimvoid
153244971SjkimAcpiUtStrupr (
154244971Sjkim    char                    *SrcString)
155244971Sjkim{
156244971Sjkim    char                    *String;
157244971Sjkim
158244971Sjkim
159244971Sjkim    ACPI_FUNCTION_ENTRY ();
160244971Sjkim
161244971Sjkim
162244971Sjkim    if (!SrcString)
163244971Sjkim    {
164244971Sjkim        return;
165244971Sjkim    }
166244971Sjkim
167244971Sjkim    /* Walk entire string, uppercasing the letters */
168244971Sjkim
169244971Sjkim    for (String = SrcString; *String; String++)
170244971Sjkim    {
171244971Sjkim        *String = (char) ACPI_TOUPPER (*String);
172244971Sjkim    }
173244971Sjkim
174244971Sjkim    return;
175244971Sjkim}
176244971Sjkim
177244971Sjkim
178244971Sjkim/*******************************************************************************
179244971Sjkim *
180244971Sjkim * FUNCTION:    AcpiUtStrtoul64
181244971Sjkim *
182244971Sjkim * PARAMETERS:  String          - Null terminated string
183244971Sjkim *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
184244971Sjkim *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
185244971Sjkim *              RetInteger      - Where the converted integer is returned
186244971Sjkim *
187244971Sjkim * RETURN:      Status and Converted value
188244971Sjkim *
189244971Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a
190244971Sjkim *              32-bit or 64-bit conversion, depending on the current mode
191244971Sjkim *              of the interpreter.
192244971Sjkim *              NOTE: Does not support Octal strings, not needed.
193244971Sjkim *
194244971Sjkim ******************************************************************************/
195244971Sjkim
196244971SjkimACPI_STATUS
197244971SjkimAcpiUtStrtoul64 (
198244971Sjkim    char                    *String,
199244971Sjkim    UINT32                  Base,
200244971Sjkim    UINT64                  *RetInteger)
201244971Sjkim{
202244971Sjkim    UINT32                  ThisDigit = 0;
203244971Sjkim    UINT64                  ReturnValue = 0;
204244971Sjkim    UINT64                  Quotient;
205244971Sjkim    UINT64                  Dividend;
206244971Sjkim    UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
207244971Sjkim    UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
208244971Sjkim    UINT8                   ValidDigits = 0;
209244971Sjkim    UINT8                   SignOf0x = 0;
210244971Sjkim    UINT8                   Term = 0;
211244971Sjkim
212244971Sjkim
213244971Sjkim    ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
214244971Sjkim
215244971Sjkim
216244971Sjkim    switch (Base)
217244971Sjkim    {
218244971Sjkim    case ACPI_ANY_BASE:
219244971Sjkim    case 16:
220250838Sjkim
221244971Sjkim        break;
222244971Sjkim
223244971Sjkim    default:
224250838Sjkim
225244971Sjkim        /* Invalid Base */
226250838Sjkim
227244971Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
228244971Sjkim    }
229244971Sjkim
230244971Sjkim    if (!String)
231244971Sjkim    {
232244971Sjkim        goto ErrorExit;
233244971Sjkim    }
234244971Sjkim
235244971Sjkim    /* Skip over any white space in the buffer */
236244971Sjkim
237244971Sjkim    while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
238244971Sjkim    {
239244971Sjkim        String++;
240244971Sjkim    }
241244971Sjkim
242244971Sjkim    if (ToIntegerOp)
243244971Sjkim    {
244244971Sjkim        /*
245244971Sjkim         * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
246244971Sjkim         * We need to determine if it is decimal or hexadecimal.
247244971Sjkim         */
248244971Sjkim        if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
249244971Sjkim        {
250244971Sjkim            SignOf0x = 1;
251244971Sjkim            Base = 16;
252244971Sjkim
253244971Sjkim            /* Skip over the leading '0x' */
254244971Sjkim            String += 2;
255244971Sjkim        }
256244971Sjkim        else
257244971Sjkim        {
258244971Sjkim            Base = 10;
259244971Sjkim        }
260244971Sjkim    }
261244971Sjkim
262244971Sjkim    /* Any string left? Check that '0x' is not followed by white space. */
263244971Sjkim
264244971Sjkim    if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
265244971Sjkim    {
266244971Sjkim        if (ToIntegerOp)
267244971Sjkim        {
268244971Sjkim            goto ErrorExit;
269244971Sjkim        }
270244971Sjkim        else
271244971Sjkim        {
272244971Sjkim            goto AllDone;
273244971Sjkim        }
274244971Sjkim    }
275244971Sjkim
276244971Sjkim    /*
277244971Sjkim     * Perform a 32-bit or 64-bit conversion, depending upon the current
278244971Sjkim     * execution mode of the interpreter
279244971Sjkim     */
280244971Sjkim    Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
281244971Sjkim
282244971Sjkim    /* Main loop: convert the string to a 32- or 64-bit integer */
283244971Sjkim
284244971Sjkim    while (*String)
285244971Sjkim    {
286244971Sjkim        if (ACPI_IS_DIGIT (*String))
287244971Sjkim        {
288244971Sjkim            /* Convert ASCII 0-9 to Decimal value */
289244971Sjkim
290244971Sjkim            ThisDigit = ((UINT8) *String) - '0';
291244971Sjkim        }
292244971Sjkim        else if (Base == 10)
293244971Sjkim        {
294244971Sjkim            /* Digit is out of range; possible in ToInteger case only */
295244971Sjkim
296244971Sjkim            Term = 1;
297244971Sjkim        }
298244971Sjkim        else
299244971Sjkim        {
300244971Sjkim            ThisDigit = (UINT8) ACPI_TOUPPER (*String);
301244971Sjkim            if (ACPI_IS_XDIGIT ((char) ThisDigit))
302244971Sjkim            {
303244971Sjkim                /* Convert ASCII Hex char to value */
304244971Sjkim
305244971Sjkim                ThisDigit = ThisDigit - 'A' + 10;
306244971Sjkim            }
307244971Sjkim            else
308244971Sjkim            {
309244971Sjkim                Term = 1;
310244971Sjkim            }
311244971Sjkim        }
312244971Sjkim
313244971Sjkim        if (Term)
314244971Sjkim        {
315244971Sjkim            if (ToIntegerOp)
316244971Sjkim            {
317244971Sjkim                goto ErrorExit;
318244971Sjkim            }
319244971Sjkim            else
320244971Sjkim            {
321244971Sjkim                break;
322244971Sjkim            }
323244971Sjkim        }
324244971Sjkim        else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
325244971Sjkim        {
326244971Sjkim            /* Skip zeros */
327244971Sjkim            String++;
328244971Sjkim            continue;
329244971Sjkim        }
330244971Sjkim
331244971Sjkim        ValidDigits++;
332244971Sjkim
333244971Sjkim        if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
334244971Sjkim        {
335244971Sjkim            /*
336244971Sjkim             * This is ToInteger operation case.
337244971Sjkim             * No any restrictions for string-to-integer conversion,
338244971Sjkim             * see ACPI spec.
339244971Sjkim             */
340244971Sjkim            goto ErrorExit;
341244971Sjkim        }
342244971Sjkim
343244971Sjkim        /* Divide the digit into the correct position */
344244971Sjkim
345244971Sjkim        (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
346244971Sjkim                    Base, &Quotient, NULL);
347244971Sjkim
348244971Sjkim        if (ReturnValue > Quotient)
349244971Sjkim        {
350244971Sjkim            if (ToIntegerOp)
351244971Sjkim            {
352244971Sjkim                goto ErrorExit;
353244971Sjkim            }
354244971Sjkim            else
355244971Sjkim            {
356244971Sjkim                break;
357244971Sjkim            }
358244971Sjkim        }
359244971Sjkim
360244971Sjkim        ReturnValue *= Base;
361244971Sjkim        ReturnValue += ThisDigit;
362244971Sjkim        String++;
363244971Sjkim    }
364244971Sjkim
365244971Sjkim    /* All done, normal exit */
366244971Sjkim
367244971SjkimAllDone:
368244971Sjkim
369244971Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
370244971Sjkim        ACPI_FORMAT_UINT64 (ReturnValue)));
371244971Sjkim
372244971Sjkim    *RetInteger = ReturnValue;
373244971Sjkim    return_ACPI_STATUS (AE_OK);
374244971Sjkim
375244971Sjkim
376244971SjkimErrorExit:
377244971Sjkim    /* Base was set/validated above */
378244971Sjkim
379244971Sjkim    if (Base == 10)
380244971Sjkim    {
381244971Sjkim        return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
382244971Sjkim    }
383244971Sjkim    else
384244971Sjkim    {
385244971Sjkim        return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
386244971Sjkim    }
387244971Sjkim}
388244971Sjkim
389244971Sjkim
390244971Sjkim/*******************************************************************************
391244971Sjkim *
392244971Sjkim * FUNCTION:    AcpiUtPrintString
393244971Sjkim *
394244971Sjkim * PARAMETERS:  String          - Null terminated ASCII string
395252279Sjkim *              MaxLength       - Maximum output length. Used to constrain the
396252279Sjkim *                                length of strings during debug output only.
397244971Sjkim *
398244971Sjkim * RETURN:      None
399244971Sjkim *
400244971Sjkim * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
401244971Sjkim *              sequences.
402244971Sjkim *
403244971Sjkim ******************************************************************************/
404244971Sjkim
405244971Sjkimvoid
406244971SjkimAcpiUtPrintString (
407244971Sjkim    char                    *String,
408252279Sjkim    UINT16                  MaxLength)
409244971Sjkim{
410244971Sjkim    UINT32                  i;
411244971Sjkim
412244971Sjkim
413244971Sjkim    if (!String)
414244971Sjkim    {
415244971Sjkim        AcpiOsPrintf ("<\"NULL STRING PTR\">");
416244971Sjkim        return;
417244971Sjkim    }
418244971Sjkim
419244971Sjkim    AcpiOsPrintf ("\"");
420281075Sdim    for (i = 0; (i < MaxLength) && String[i]; i++)
421244971Sjkim    {
422244971Sjkim        /* Escape sequences */
423244971Sjkim
424244971Sjkim        switch (String[i])
425244971Sjkim        {
426244971Sjkim        case 0x07:
427250838Sjkim
428244971Sjkim            AcpiOsPrintf ("\\a");       /* BELL */
429244971Sjkim            break;
430244971Sjkim
431244971Sjkim        case 0x08:
432250838Sjkim
433244971Sjkim            AcpiOsPrintf ("\\b");       /* BACKSPACE */
434244971Sjkim            break;
435244971Sjkim
436244971Sjkim        case 0x0C:
437250838Sjkim
438244971Sjkim            AcpiOsPrintf ("\\f");       /* FORMFEED */
439244971Sjkim            break;
440244971Sjkim
441244971Sjkim        case 0x0A:
442250838Sjkim
443244971Sjkim            AcpiOsPrintf ("\\n");       /* LINEFEED */
444244971Sjkim            break;
445244971Sjkim
446244971Sjkim        case 0x0D:
447250838Sjkim
448244971Sjkim            AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
449244971Sjkim            break;
450244971Sjkim
451244971Sjkim        case 0x09:
452250838Sjkim
453244971Sjkim            AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
454244971Sjkim            break;
455244971Sjkim
456244971Sjkim        case 0x0B:
457250838Sjkim
458244971Sjkim            AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
459244971Sjkim            break;
460244971Sjkim
461244971Sjkim        case '\'':                      /* Single Quote */
462244971Sjkim        case '\"':                      /* Double Quote */
463244971Sjkim        case '\\':                      /* Backslash */
464250838Sjkim
465244971Sjkim            AcpiOsPrintf ("\\%c", (int) String[i]);
466244971Sjkim            break;
467244971Sjkim
468244971Sjkim        default:
469244971Sjkim
470244971Sjkim            /* Check for printable character or hex escape */
471244971Sjkim
472244971Sjkim            if (ACPI_IS_PRINT (String[i]))
473244971Sjkim            {
474244971Sjkim                /* This is a normal character */
475244971Sjkim
476244971Sjkim                AcpiOsPrintf ("%c", (int) String[i]);
477244971Sjkim            }
478244971Sjkim            else
479244971Sjkim            {
480244971Sjkim                /* All others will be Hex escapes */
481244971Sjkim
482244971Sjkim                AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
483244971Sjkim            }
484244971Sjkim            break;
485244971Sjkim        }
486244971Sjkim    }
487244971Sjkim    AcpiOsPrintf ("\"");
488244971Sjkim
489244971Sjkim    if (i == MaxLength && String[i])
490244971Sjkim    {
491244971Sjkim        AcpiOsPrintf ("...");
492244971Sjkim    }
493244971Sjkim}
494244971Sjkim
495244971Sjkim
496244971Sjkim/*******************************************************************************
497244971Sjkim *
498244971Sjkim * FUNCTION:    AcpiUtValidAcpiChar
499244971Sjkim *
500244971Sjkim * PARAMETERS:  Char            - The character to be examined
501244971Sjkim *              Position        - Byte position (0-3)
502244971Sjkim *
503244971Sjkim * RETURN:      TRUE if the character is valid, FALSE otherwise
504244971Sjkim *
505244971Sjkim * DESCRIPTION: Check for a valid ACPI character. Must be one of:
506244971Sjkim *              1) Upper case alpha
507244971Sjkim *              2) numeric
508244971Sjkim *              3) underscore
509244971Sjkim *
510244971Sjkim *              We allow a '!' as the last character because of the ASF! table
511244971Sjkim *
512244971Sjkim ******************************************************************************/
513244971Sjkim
514244971SjkimBOOLEAN
515244971SjkimAcpiUtValidAcpiChar (
516244971Sjkim    char                    Character,
517244971Sjkim    UINT32                  Position)
518244971Sjkim{
519244971Sjkim
520244971Sjkim    if (!((Character >= 'A' && Character <= 'Z') ||
521244971Sjkim          (Character >= '0' && Character <= '9') ||
522244971Sjkim          (Character == '_')))
523244971Sjkim    {
524244971Sjkim        /* Allow a '!' in the last position */
525244971Sjkim
526244971Sjkim        if (Character == '!' && Position == 3)
527244971Sjkim        {
528244971Sjkim            return (TRUE);
529244971Sjkim        }
530244971Sjkim
531244971Sjkim        return (FALSE);
532244971Sjkim    }
533244971Sjkim
534244971Sjkim    return (TRUE);
535244971Sjkim}
536244971Sjkim
537244971Sjkim
538244971Sjkim/*******************************************************************************
539244971Sjkim *
540244971Sjkim * FUNCTION:    AcpiUtValidAcpiName
541244971Sjkim *
542250838Sjkim * PARAMETERS:  Name            - The name to be examined. Does not have to
543250838Sjkim *                                be NULL terminated string.
544244971Sjkim *
545244971Sjkim * RETURN:      TRUE if the name is valid, FALSE otherwise
546244971Sjkim *
547244971Sjkim * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
548244971Sjkim *              1) Upper case alpha
549244971Sjkim *              2) numeric
550244971Sjkim *              3) underscore
551244971Sjkim *
552244971Sjkim ******************************************************************************/
553244971Sjkim
554244971SjkimBOOLEAN
555244971SjkimAcpiUtValidAcpiName (
556250838Sjkim    char                    *Name)
557244971Sjkim{
558244971Sjkim    UINT32                  i;
559244971Sjkim
560244971Sjkim
561244971Sjkim    ACPI_FUNCTION_ENTRY ();
562244971Sjkim
563244971Sjkim
564244971Sjkim    for (i = 0; i < ACPI_NAME_SIZE; i++)
565244971Sjkim    {
566250838Sjkim        if (!AcpiUtValidAcpiChar (Name[i], i))
567244971Sjkim        {
568244971Sjkim            return (FALSE);
569244971Sjkim        }
570244971Sjkim    }
571244971Sjkim
572244971Sjkim    return (TRUE);
573244971Sjkim}
574244971Sjkim
575244971Sjkim
576244971Sjkim/*******************************************************************************
577244971Sjkim *
578244971Sjkim * FUNCTION:    AcpiUtRepairName
579244971Sjkim *
580244971Sjkim * PARAMETERS:  Name            - The ACPI name to be repaired
581244971Sjkim *
582244971Sjkim * RETURN:      Repaired version of the name
583244971Sjkim *
584244971Sjkim * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
585244971Sjkim *              return the new name. NOTE: the Name parameter must reside in
586244971Sjkim *              read/write memory, cannot be a const.
587244971Sjkim *
588244971Sjkim * An ACPI Name must consist of valid ACPI characters. We will repair the name
589244971Sjkim * if necessary because we don't want to abort because of this, but we want
590244971Sjkim * all namespace names to be printable. A warning message is appropriate.
591244971Sjkim *
592244971Sjkim * This issue came up because there are in fact machines that exhibit
593244971Sjkim * this problem, and we want to be able to enable ACPI support for them,
594244971Sjkim * even though there are a few bad names.
595244971Sjkim *
596244971Sjkim ******************************************************************************/
597244971Sjkim
598244971Sjkimvoid
599244971SjkimAcpiUtRepairName (
600244971Sjkim    char                    *Name)
601244971Sjkim{
602244971Sjkim    UINT32                  i;
603244971Sjkim    BOOLEAN                 FoundBadChar = FALSE;
604244971Sjkim    UINT32                  OriginalName;
605244971Sjkim
606244971Sjkim
607244971Sjkim    ACPI_FUNCTION_NAME (UtRepairName);
608244971Sjkim
609244971Sjkim
610244971Sjkim    ACPI_MOVE_NAME (&OriginalName, Name);
611244971Sjkim
612244971Sjkim    /* Check each character in the name */
613244971Sjkim
614244971Sjkim    for (i = 0; i < ACPI_NAME_SIZE; i++)
615244971Sjkim    {
616244971Sjkim        if (AcpiUtValidAcpiChar (Name[i], i))
617244971Sjkim        {
618244971Sjkim            continue;
619244971Sjkim        }
620244971Sjkim
621244971Sjkim        /*
622244971Sjkim         * Replace a bad character with something printable, yet technically
623244971Sjkim         * still invalid. This prevents any collisions with existing "good"
624244971Sjkim         * names in the namespace.
625244971Sjkim         */
626244971Sjkim        Name[i] = '*';
627244971Sjkim        FoundBadChar = TRUE;
628244971Sjkim    }
629244971Sjkim
630244971Sjkim    if (FoundBadChar)
631244971Sjkim    {
632244971Sjkim        /* Report warning only if in strict mode or debug mode */
633244971Sjkim
634244971Sjkim        if (!AcpiGbl_EnableInterpreterSlack)
635244971Sjkim        {
636244971Sjkim            ACPI_WARNING ((AE_INFO,
637244971Sjkim                "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
638244971Sjkim                OriginalName, Name));
639244971Sjkim        }
640244971Sjkim        else
641244971Sjkim        {
642244971Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
643244971Sjkim                "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
644244971Sjkim                OriginalName, Name));
645244971Sjkim        }
646244971Sjkim    }
647244971Sjkim}
648244971Sjkim
649244971Sjkim
650244971Sjkim#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
651244971Sjkim/*******************************************************************************
652244971Sjkim *
653244971Sjkim * FUNCTION:    UtConvertBackslashes
654244971Sjkim *
655244971Sjkim * PARAMETERS:  Pathname        - File pathname string to be converted
656244971Sjkim *
657244971Sjkim * RETURN:      Modifies the input Pathname
658244971Sjkim *
659244971Sjkim * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
660244971Sjkim *              the entire input file pathname string.
661244971Sjkim *
662244971Sjkim ******************************************************************************/
663244971Sjkim
664244971Sjkimvoid
665244971SjkimUtConvertBackslashes (
666244971Sjkim    char                    *Pathname)
667244971Sjkim{
668244971Sjkim
669244971Sjkim    if (!Pathname)
670244971Sjkim    {
671244971Sjkim        return;
672244971Sjkim    }
673244971Sjkim
674244971Sjkim    while (*Pathname)
675244971Sjkim    {
676244971Sjkim        if (*Pathname == '\\')
677244971Sjkim        {
678244971Sjkim            *Pathname = '/';
679244971Sjkim        }
680244971Sjkim
681244971Sjkim        Pathname++;
682244971Sjkim    }
683244971Sjkim}
684244971Sjkim#endif
685281075Sdim
686281075Sdim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
687281075Sdim/*******************************************************************************
688281075Sdim *
689281075Sdim * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
690281075Sdim *
691281075Sdim * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
692281075Sdim *              functions. This is the size of the Destination buffer.
693281075Sdim *
694281075Sdim * RETURN:      TRUE if the operation would overflow the destination buffer.
695281075Sdim *
696281075Sdim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
697281075Sdim *              the result of the operation will not overflow the output string
698281075Sdim *              buffer.
699281075Sdim *
700281075Sdim * NOTE:        These functions are typically only helpful for processing
701281075Sdim *              user input and command lines. For most ACPICA code, the
702281075Sdim *              required buffer length is precisely calculated before buffer
703281075Sdim *              allocation, so the use of these functions is unnecessary.
704281075Sdim *
705281075Sdim ******************************************************************************/
706281075Sdim
707281075SdimBOOLEAN
708281075SdimAcpiUtSafeStrcpy (
709281075Sdim    char                    *Dest,
710281075Sdim    ACPI_SIZE               DestSize,
711281075Sdim    char                    *Source)
712281075Sdim{
713281075Sdim
714281075Sdim    if (ACPI_STRLEN (Source) >= DestSize)
715281075Sdim    {
716281075Sdim        return (TRUE);
717281075Sdim    }
718281075Sdim
719281075Sdim    ACPI_STRCPY (Dest, Source);
720281075Sdim    return (FALSE);
721281075Sdim}
722281075Sdim
723281075SdimBOOLEAN
724281075SdimAcpiUtSafeStrcat (
725281075Sdim    char                    *Dest,
726281075Sdim    ACPI_SIZE               DestSize,
727281075Sdim    char                    *Source)
728281075Sdim{
729281075Sdim
730281075Sdim    if ((ACPI_STRLEN (Dest) + ACPI_STRLEN (Source)) >= DestSize)
731281075Sdim    {
732281075Sdim        return (TRUE);
733281075Sdim    }
734281075Sdim
735281075Sdim    ACPI_STRCAT (Dest, Source);
736281075Sdim    return (FALSE);
737281075Sdim}
738281075Sdim
739281075Sdim#ifndef _KERNEL
740281075SdimBOOLEAN
741281075SdimAcpiUtSafeStrncat (
742281075Sdim    char                    *Dest,
743281075Sdim    ACPI_SIZE               DestSize,
744281075Sdim    char                    *Source,
745281075Sdim    ACPI_SIZE               MaxTransferLength)
746281075Sdim{
747281075Sdim    ACPI_SIZE               ActualTransferLength;
748281075Sdim
749281075Sdim
750281075Sdim    ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source));
751281075Sdim
752281075Sdim    if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize)
753281075Sdim    {
754281075Sdim        return (TRUE);
755281075Sdim    }
756281075Sdim
757281075Sdim    ACPI_STRNCAT (Dest, Source, MaxTransferLength);
758281075Sdim    return (FALSE);
759281075Sdim}
760281075Sdim#endif
761281075Sdim
762281075Sdim#endif
763