1285728Sjkim/*******************************************************************************
2285728Sjkim *
3285728Sjkim * Module Name: utnonansi - Non-ansi C library functions
4285728Sjkim *
5285728Sjkim ******************************************************************************/
6285728Sjkim
7285728Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9285728Sjkim * All rights reserved.
10285728Sjkim *
11285728Sjkim * Redistribution and use in source and binary forms, with or without
12285728Sjkim * modification, are permitted provided that the following conditions
13285728Sjkim * are met:
14285728Sjkim * 1. Redistributions of source code must retain the above copyright
15285728Sjkim *    notice, this list of conditions, and the following disclaimer,
16285728Sjkim *    without modification.
17285728Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18285728Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19285728Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20285728Sjkim *    including a substantially similar Disclaimer requirement for further
21285728Sjkim *    binary redistribution.
22285728Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23285728Sjkim *    of any contributors may be used to endorse or promote products derived
24285728Sjkim *    from this software without specific prior written permission.
25285728Sjkim *
26285728Sjkim * Alternatively, this software may be distributed under the terms of the
27285728Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28285728Sjkim * Software Foundation.
29285728Sjkim *
30285728Sjkim * NO WARRANTY
31285728Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32285728Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33285728Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34285728Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35285728Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36285728Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37285728Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38285728Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39285728Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40285728Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41285728Sjkim * POSSIBILITY OF SUCH DAMAGES.
42285728Sjkim */
43285728Sjkim
44285797Sjkim#include <contrib/dev/acpica/include/acpi.h>
45285797Sjkim#include <contrib/dev/acpica/include/accommon.h>
46285728Sjkim
47285728Sjkim
48285728Sjkim#define _COMPONENT          ACPI_UTILITIES
49285728Sjkim        ACPI_MODULE_NAME    ("utnonansi")
50285728Sjkim
51285728Sjkim
52285728Sjkim/*
53285728Sjkim * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
54285728Sjkim * version of strtoul.
55285728Sjkim */
56285728Sjkim
57285728Sjkim/*******************************************************************************
58285728Sjkim *
59285728Sjkim * FUNCTION:    AcpiUtStrlwr (strlwr)
60285728Sjkim *
61285728Sjkim * PARAMETERS:  SrcString       - The source string to convert
62285728Sjkim *
63285728Sjkim * RETURN:      None
64285728Sjkim *
65285728Sjkim * DESCRIPTION: Convert a string to lowercase
66285728Sjkim *
67285728Sjkim ******************************************************************************/
68285728Sjkim
69285728Sjkimvoid
70285728SjkimAcpiUtStrlwr (
71285728Sjkim    char                    *SrcString)
72285728Sjkim{
73285728Sjkim    char                    *String;
74285728Sjkim
75285728Sjkim
76285728Sjkim    ACPI_FUNCTION_ENTRY ();
77285728Sjkim
78285728Sjkim
79285728Sjkim    if (!SrcString)
80285728Sjkim    {
81285728Sjkim        return;
82285728Sjkim    }
83285728Sjkim
84285728Sjkim    /* Walk entire string, lowercasing the letters */
85285728Sjkim
86285728Sjkim    for (String = SrcString; *String; String++)
87285728Sjkim    {
88285728Sjkim        *String = (char) tolower ((int) *String);
89285728Sjkim    }
90285728Sjkim}
91285728Sjkim
92285728Sjkim
93285728Sjkim/*******************************************************************************
94285728Sjkim *
95285728Sjkim * FUNCTION:    AcpiUtStrupr (strupr)
96285728Sjkim *
97285728Sjkim * PARAMETERS:  SrcString       - The source string to convert
98285728Sjkim *
99285728Sjkim * RETURN:      None
100285728Sjkim *
101285728Sjkim * DESCRIPTION: Convert a string to uppercase
102285728Sjkim *
103285728Sjkim ******************************************************************************/
104285728Sjkim
105285728Sjkimvoid
106285728SjkimAcpiUtStrupr (
107285728Sjkim    char                    *SrcString)
108285728Sjkim{
109285728Sjkim    char                    *String;
110285728Sjkim
111285728Sjkim
112285728Sjkim    ACPI_FUNCTION_ENTRY ();
113285728Sjkim
114285728Sjkim
115285728Sjkim    if (!SrcString)
116285728Sjkim    {
117285728Sjkim        return;
118285728Sjkim    }
119285728Sjkim
120285728Sjkim    /* Walk entire string, uppercasing the letters */
121285728Sjkim
122285728Sjkim    for (String = SrcString; *String; String++)
123285728Sjkim    {
124285728Sjkim        *String = (char) toupper ((int) *String);
125285728Sjkim    }
126285728Sjkim}
127285728Sjkim
128285728Sjkim
129285728Sjkim/******************************************************************************
130285728Sjkim *
131285728Sjkim * FUNCTION:    AcpiUtStricmp (stricmp)
132285728Sjkim *
133285728Sjkim * PARAMETERS:  String1             - first string to compare
134285728Sjkim *              String2             - second string to compare
135285728Sjkim *
136285728Sjkim * RETURN:      int that signifies string relationship. Zero means strings
137285728Sjkim *              are equal.
138285728Sjkim *
139285728Sjkim * DESCRIPTION: Case-insensitive string compare. Implementation of the
140285728Sjkim *              non-ANSI stricmp function.
141285728Sjkim *
142285728Sjkim ******************************************************************************/
143285728Sjkim
144285728Sjkimint
145285728SjkimAcpiUtStricmp (
146285728Sjkim    char                    *String1,
147285728Sjkim    char                    *String2)
148285728Sjkim{
149285728Sjkim    int                     c1;
150285728Sjkim    int                     c2;
151285728Sjkim
152285728Sjkim
153285728Sjkim    do
154285728Sjkim    {
155285728Sjkim        c1 = tolower ((int) *String1);
156285728Sjkim        c2 = tolower ((int) *String2);
157285728Sjkim
158285728Sjkim        String1++;
159285728Sjkim        String2++;
160285728Sjkim    }
161285728Sjkim    while ((c1 == c2) && (c1));
162285728Sjkim
163285728Sjkim    return (c1 - c2);
164285728Sjkim}
165285728Sjkim
166285728Sjkim
167298714Sjkim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
168285728Sjkim/*******************************************************************************
169285728Sjkim *
170298714Sjkim * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
171298714Sjkim *
172298714Sjkim * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
173298714Sjkim *              functions. This is the size of the Destination buffer.
174298714Sjkim *
175298714Sjkim * RETURN:      TRUE if the operation would overflow the destination buffer.
176298714Sjkim *
177298714Sjkim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
178298714Sjkim *              the result of the operation will not overflow the output string
179298714Sjkim *              buffer.
180298714Sjkim *
181298714Sjkim * NOTE:        These functions are typically only helpful for processing
182298714Sjkim *              user input and command lines. For most ACPICA code, the
183298714Sjkim *              required buffer length is precisely calculated before buffer
184298714Sjkim *              allocation, so the use of these functions is unnecessary.
185298714Sjkim *
186298714Sjkim ******************************************************************************/
187298714Sjkim
188298714SjkimBOOLEAN
189298714SjkimAcpiUtSafeStrcpy (
190298714Sjkim    char                    *Dest,
191298714Sjkim    ACPI_SIZE               DestSize,
192298714Sjkim    char                    *Source)
193298714Sjkim{
194298714Sjkim
195298714Sjkim    if (strlen (Source) >= DestSize)
196298714Sjkim    {
197298714Sjkim        return (TRUE);
198298714Sjkim    }
199298714Sjkim
200298714Sjkim    strcpy (Dest, Source);
201298714Sjkim    return (FALSE);
202298714Sjkim}
203298714Sjkim
204298714SjkimBOOLEAN
205298714SjkimAcpiUtSafeStrcat (
206298714Sjkim    char                    *Dest,
207298714Sjkim    ACPI_SIZE               DestSize,
208298714Sjkim    char                    *Source)
209298714Sjkim{
210298714Sjkim
211298714Sjkim    if ((strlen (Dest) + strlen (Source)) >= DestSize)
212298714Sjkim    {
213298714Sjkim        return (TRUE);
214298714Sjkim    }
215298714Sjkim
216298714Sjkim    strcat (Dest, Source);
217298714Sjkim    return (FALSE);
218298714Sjkim}
219298714Sjkim
220298714SjkimBOOLEAN
221298714SjkimAcpiUtSafeStrncat (
222298714Sjkim    char                    *Dest,
223298714Sjkim    ACPI_SIZE               DestSize,
224298714Sjkim    char                    *Source,
225298714Sjkim    ACPI_SIZE               MaxTransferLength)
226298714Sjkim{
227298714Sjkim    ACPI_SIZE               ActualTransferLength;
228298714Sjkim
229298714Sjkim
230298714Sjkim    ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
231298714Sjkim
232298714Sjkim    if ((strlen (Dest) + ActualTransferLength) >= DestSize)
233298714Sjkim    {
234298714Sjkim        return (TRUE);
235298714Sjkim    }
236298714Sjkim
237298714Sjkim    strncat (Dest, Source, MaxTransferLength);
238298714Sjkim    return (FALSE);
239298714Sjkim}
240298714Sjkim#endif
241298714Sjkim
242298714Sjkim
243298714Sjkim/*******************************************************************************
244298714Sjkim *
245285728Sjkim * FUNCTION:    AcpiUtStrtoul64
246285728Sjkim *
247298714Sjkim * PARAMETERS:  String                  - Null terminated string
248298714Sjkim *              Base                    - Radix of the string: 16 or 10 or
249298714Sjkim *                                        ACPI_ANY_BASE
250298714Sjkim *              MaxIntegerByteWidth     - Maximum allowable integer,in bytes:
251298714Sjkim *                                        4 or 8 (32 or 64 bits)
252298714Sjkim *              RetInteger              - Where the converted integer is
253298714Sjkim *                                        returned
254285728Sjkim *
255285728Sjkim * RETURN:      Status and Converted value
256285728Sjkim *
257285728Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a
258298714Sjkim *              32-bit or 64-bit conversion, depending on the input integer
259298714Sjkim *              size (often the current mode of the interpreter).
260285728Sjkim *
261298714Sjkim * NOTES:       Negative numbers are not supported, as they are not supported
262298714Sjkim *              by ACPI.
263285728Sjkim *
264298714Sjkim *              AcpiGbl_IntegerByteWidth should be set to the proper width.
265298714Sjkim *              For the core ACPICA code, this width depends on the DSDT
266298714Sjkim *              version. For iASL, the default byte width is always 8 for the
267298714Sjkim *              parser, but error checking is performed later to flag cases
268298714Sjkim *              where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
269298714Sjkim *
270298714Sjkim *              Does not support Octal strings, not needed at this time.
271298714Sjkim *
272285728Sjkim ******************************************************************************/
273285728Sjkim
274285728SjkimACPI_STATUS
275285728SjkimAcpiUtStrtoul64 (
276285728Sjkim    char                    *String,
277285728Sjkim    UINT32                  Base,
278298714Sjkim    UINT32                  MaxIntegerByteWidth,
279285728Sjkim    UINT64                  *RetInteger)
280285728Sjkim{
281285728Sjkim    UINT32                  ThisDigit = 0;
282285728Sjkim    UINT64                  ReturnValue = 0;
283285728Sjkim    UINT64                  Quotient;
284285728Sjkim    UINT64                  Dividend;
285285728Sjkim    UINT8                   ValidDigits = 0;
286285728Sjkim    UINT8                   SignOf0x = 0;
287285728Sjkim    UINT8                   Term = 0;
288285728Sjkim
289285728Sjkim
290298714Sjkim    ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
291285728Sjkim
292285728Sjkim
293285728Sjkim    switch (Base)
294285728Sjkim    {
295285728Sjkim    case ACPI_ANY_BASE:
296298714Sjkim    case 10:
297285728Sjkim    case 16:
298285728Sjkim
299285728Sjkim        break;
300285728Sjkim
301285728Sjkim    default:
302285728Sjkim
303285728Sjkim        /* Invalid Base */
304285728Sjkim
305285728Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
306285728Sjkim    }
307285728Sjkim
308285728Sjkim    if (!String)
309285728Sjkim    {
310285728Sjkim        goto ErrorExit;
311285728Sjkim    }
312285728Sjkim
313285728Sjkim    /* Skip over any white space in the buffer */
314285728Sjkim
315285728Sjkim    while ((*String) && (isspace ((int) *String) || *String == '\t'))
316285728Sjkim    {
317285728Sjkim        String++;
318285728Sjkim    }
319285728Sjkim
320298714Sjkim    if (Base == ACPI_ANY_BASE)
321285728Sjkim    {
322285728Sjkim        /*
323298714Sjkim         * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'.
324285728Sjkim         * We need to determine if it is decimal or hexadecimal.
325285728Sjkim         */
326285728Sjkim        if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
327285728Sjkim        {
328285728Sjkim            SignOf0x = 1;
329285728Sjkim            Base = 16;
330285728Sjkim
331285728Sjkim            /* Skip over the leading '0x' */
332285728Sjkim            String += 2;
333285728Sjkim        }
334285728Sjkim        else
335285728Sjkim        {
336285728Sjkim            Base = 10;
337285728Sjkim        }
338285728Sjkim    }
339285728Sjkim
340285728Sjkim    /* Any string left? Check that '0x' is not followed by white space. */
341285728Sjkim
342285728Sjkim    if (!(*String) || isspace ((int) *String) || *String == '\t')
343285728Sjkim    {
344298714Sjkim        if (Base == ACPI_ANY_BASE)
345285728Sjkim        {
346285728Sjkim            goto ErrorExit;
347285728Sjkim        }
348285728Sjkim        else
349285728Sjkim        {
350285728Sjkim            goto AllDone;
351285728Sjkim        }
352285728Sjkim    }
353285728Sjkim
354285728Sjkim    /*
355298714Sjkim     * Perform a 32-bit or 64-bit conversion, depending upon the input
356298714Sjkim     * byte width
357285728Sjkim     */
358298714Sjkim    Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ?
359298714Sjkim        ACPI_UINT32_MAX : ACPI_UINT64_MAX;
360285728Sjkim
361285728Sjkim    /* Main loop: convert the string to a 32- or 64-bit integer */
362285728Sjkim
363285728Sjkim    while (*String)
364285728Sjkim    {
365285728Sjkim        if (isdigit ((int) *String))
366285728Sjkim        {
367285728Sjkim            /* Convert ASCII 0-9 to Decimal value */
368285728Sjkim
369285728Sjkim            ThisDigit = ((UINT8) *String) - '0';
370285728Sjkim        }
371285728Sjkim        else if (Base == 10)
372285728Sjkim        {
373285728Sjkim            /* Digit is out of range; possible in ToInteger case only */
374285728Sjkim
375285728Sjkim            Term = 1;
376285728Sjkim        }
377285728Sjkim        else
378285728Sjkim        {
379285728Sjkim            ThisDigit = (UINT8) toupper ((int) *String);
380285728Sjkim            if (isxdigit ((int) ThisDigit))
381285728Sjkim            {
382285728Sjkim                /* Convert ASCII Hex char to value */
383285728Sjkim
384285728Sjkim                ThisDigit = ThisDigit - 'A' + 10;
385285728Sjkim            }
386285728Sjkim            else
387285728Sjkim            {
388285728Sjkim                Term = 1;
389285728Sjkim            }
390285728Sjkim        }
391285728Sjkim
392285728Sjkim        if (Term)
393285728Sjkim        {
394298714Sjkim            if (Base == ACPI_ANY_BASE)
395285728Sjkim            {
396285728Sjkim                goto ErrorExit;
397285728Sjkim            }
398285728Sjkim            else
399285728Sjkim            {
400285728Sjkim                break;
401285728Sjkim            }
402285728Sjkim        }
403285728Sjkim        else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
404285728Sjkim        {
405285728Sjkim            /* Skip zeros */
406285728Sjkim            String++;
407285728Sjkim            continue;
408285728Sjkim        }
409285728Sjkim
410285728Sjkim        ValidDigits++;
411285728Sjkim
412298714Sjkim        if (SignOf0x && ((ValidDigits > 16) ||
413298714Sjkim            ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH))))
414285728Sjkim        {
415285728Sjkim            /*
416285728Sjkim             * This is ToInteger operation case.
417298714Sjkim             * No restrictions for string-to-integer conversion,
418285728Sjkim             * see ACPI spec.
419285728Sjkim             */
420285728Sjkim            goto ErrorExit;
421285728Sjkim        }
422285728Sjkim
423285728Sjkim        /* Divide the digit into the correct position */
424285728Sjkim
425298714Sjkim        (void) AcpiUtShortDivide (
426298714Sjkim            (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL);
427285728Sjkim
428285728Sjkim        if (ReturnValue > Quotient)
429285728Sjkim        {
430298714Sjkim            if (Base == ACPI_ANY_BASE)
431285728Sjkim            {
432285728Sjkim                goto ErrorExit;
433285728Sjkim            }
434285728Sjkim            else
435285728Sjkim            {
436285728Sjkim                break;
437285728Sjkim            }
438285728Sjkim        }
439285728Sjkim
440285728Sjkim        ReturnValue *= Base;
441285728Sjkim        ReturnValue += ThisDigit;
442285728Sjkim        String++;
443285728Sjkim    }
444285728Sjkim
445285728Sjkim    /* All done, normal exit */
446285728Sjkim
447285728SjkimAllDone:
448285728Sjkim
449285728Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
450285728Sjkim        ACPI_FORMAT_UINT64 (ReturnValue)));
451285728Sjkim
452285728Sjkim    *RetInteger = ReturnValue;
453285728Sjkim    return_ACPI_STATUS (AE_OK);
454285728Sjkim
455285728Sjkim
456285728SjkimErrorExit:
457285728Sjkim
458298714Sjkim    /* Base was set/validated above (10 or 16) */
459298714Sjkim
460285728Sjkim    if (Base == 10)
461285728Sjkim    {
462285728Sjkim        return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
463285728Sjkim    }
464285728Sjkim    else
465285728Sjkim    {
466285728Sjkim        return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
467285728Sjkim    }
468285728Sjkim}
469285728Sjkim
470285728Sjkim
471298714Sjkim#ifdef _OBSOLETE_FUNCTIONS
472298714Sjkim/* Removed: 01/2016 */
473298714Sjkim
474285728Sjkim/*******************************************************************************
475285728Sjkim *
476298714Sjkim * FUNCTION:    strtoul64
477285728Sjkim *
478298714Sjkim * PARAMETERS:  String              - Null terminated string
479298714Sjkim *              Terminater          - Where a pointer to the terminating byte
480298714Sjkim *                                    is returned
481298714Sjkim *              Base                - Radix of the string
482285728Sjkim *
483298714Sjkim * RETURN:      Converted value
484285728Sjkim *
485298714Sjkim * DESCRIPTION: Convert a string into an unsigned value.
486285728Sjkim *
487285728Sjkim ******************************************************************************/
488285728Sjkim
489298714SjkimACPI_STATUS
490298714Sjkimstrtoul64 (
491298714Sjkim    char                    *String,
492298714Sjkim    UINT32                  Base,
493298714Sjkim    UINT64                  *RetInteger)
494285728Sjkim{
495298714Sjkim    UINT32                  Index;
496298714Sjkim    UINT32                  Sign;
497298714Sjkim    UINT64                  ReturnValue = 0;
498298714Sjkim    ACPI_STATUS             Status = AE_OK;
499285728Sjkim
500298714Sjkim
501298714Sjkim    *RetInteger = 0;
502298714Sjkim
503298714Sjkim    switch (Base)
504285728Sjkim    {
505298714Sjkim    case 0:
506298714Sjkim    case 8:
507298714Sjkim    case 10:
508298714Sjkim    case 16:
509298714Sjkim
510298714Sjkim        break;
511298714Sjkim
512298714Sjkim    default:
513298714Sjkim        /*
514298714Sjkim         * The specified Base parameter is not in the domain of
515298714Sjkim         * this function:
516298714Sjkim         */
517298714Sjkim        return (AE_BAD_PARAMETER);
518285728Sjkim    }
519285728Sjkim
520298714Sjkim    /* Skip over any white space in the buffer: */
521285728Sjkim
522298714Sjkim    while (isspace ((int) *String) || *String == '\t')
523298714Sjkim    {
524298714Sjkim        ++String;
525298714Sjkim    }
526285728Sjkim
527298714Sjkim    /*
528298714Sjkim     * The buffer may contain an optional plus or minus sign.
529298714Sjkim     * If it does, then skip over it but remember what is was:
530298714Sjkim     */
531298714Sjkim    if (*String == '-')
532285728Sjkim    {
533298714Sjkim        Sign = ACPI_SIGN_NEGATIVE;
534298714Sjkim        ++String;
535285728Sjkim    }
536298714Sjkim    else if (*String == '+')
537298714Sjkim    {
538298714Sjkim        ++String;
539298714Sjkim        Sign = ACPI_SIGN_POSITIVE;
540298714Sjkim    }
541298714Sjkim    else
542298714Sjkim    {
543298714Sjkim        Sign = ACPI_SIGN_POSITIVE;
544298714Sjkim    }
545285728Sjkim
546298714Sjkim    /*
547298714Sjkim     * If the input parameter Base is zero, then we need to
548298714Sjkim     * determine if it is octal, decimal, or hexadecimal:
549298714Sjkim     */
550298714Sjkim    if (Base == 0)
551298714Sjkim    {
552298714Sjkim        if (*String == '0')
553298714Sjkim        {
554298714Sjkim            if (tolower ((int) *(++String)) == 'x')
555298714Sjkim            {
556298714Sjkim                Base = 16;
557298714Sjkim                ++String;
558298714Sjkim            }
559298714Sjkim            else
560298714Sjkim            {
561298714Sjkim                Base = 8;
562298714Sjkim            }
563298714Sjkim        }
564298714Sjkim        else
565298714Sjkim        {
566298714Sjkim            Base = 10;
567298714Sjkim        }
568298714Sjkim    }
569298714Sjkim
570298714Sjkim    /*
571298714Sjkim     * For octal and hexadecimal bases, skip over the leading
572298714Sjkim     * 0 or 0x, if they are present.
573298714Sjkim     */
574298714Sjkim    if (Base == 8 && *String == '0')
575298714Sjkim    {
576298714Sjkim        String++;
577298714Sjkim    }
578298714Sjkim
579298714Sjkim    if (Base == 16 &&
580298714Sjkim        *String == '0' &&
581298714Sjkim        tolower ((int) *(++String)) == 'x')
582298714Sjkim    {
583298714Sjkim        String++;
584298714Sjkim    }
585298714Sjkim
586298714Sjkim    /* Main loop: convert the string to an unsigned long */
587298714Sjkim
588298714Sjkim    while (*String)
589298714Sjkim    {
590298714Sjkim        if (isdigit ((int) *String))
591298714Sjkim        {
592298714Sjkim            Index = ((UINT8) *String) - '0';
593298714Sjkim        }
594298714Sjkim        else
595298714Sjkim        {
596298714Sjkim            Index = (UINT8) toupper ((int) *String);
597298714Sjkim            if (isupper ((int) Index))
598298714Sjkim            {
599298714Sjkim                Index = Index - 'A' + 10;
600298714Sjkim            }
601298714Sjkim            else
602298714Sjkim            {
603298714Sjkim                goto ErrorExit;
604298714Sjkim            }
605298714Sjkim        }
606298714Sjkim
607298714Sjkim        if (Index >= Base)
608298714Sjkim        {
609298714Sjkim            goto ErrorExit;
610298714Sjkim        }
611298714Sjkim
612298714Sjkim        /* Check to see if value is out of range: */
613298714Sjkim
614298714Sjkim        if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
615298714Sjkim            (UINT64) Base))
616298714Sjkim        {
617298714Sjkim            goto ErrorExit;
618298714Sjkim        }
619298714Sjkim        else
620298714Sjkim        {
621298714Sjkim            ReturnValue *= Base;
622298714Sjkim            ReturnValue += Index;
623298714Sjkim        }
624298714Sjkim
625298714Sjkim        ++String;
626298714Sjkim    }
627298714Sjkim
628298714Sjkim
629298714Sjkim    /* If a minus sign was present, then "the conversion is negated": */
630298714Sjkim
631298714Sjkim    if (Sign == ACPI_SIGN_NEGATIVE)
632298714Sjkim    {
633298714Sjkim        ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
634298714Sjkim    }
635298714Sjkim
636298714Sjkim    *RetInteger = ReturnValue;
637298714Sjkim    return (Status);
638298714Sjkim
639298714Sjkim
640298714SjkimErrorExit:
641298714Sjkim    switch (Base)
642298714Sjkim    {
643298714Sjkim    case 8:
644298714Sjkim
645298714Sjkim        Status = AE_BAD_OCTAL_CONSTANT;
646298714Sjkim        break;
647298714Sjkim
648298714Sjkim    case 10:
649298714Sjkim
650298714Sjkim        Status = AE_BAD_DECIMAL_CONSTANT;
651298714Sjkim        break;
652298714Sjkim
653298714Sjkim    case 16:
654298714Sjkim
655298714Sjkim        Status = AE_BAD_HEX_CONSTANT;
656298714Sjkim        break;
657298714Sjkim
658298714Sjkim    default:
659298714Sjkim
660298714Sjkim        /* Base validated above */
661298714Sjkim
662298714Sjkim        break;
663298714Sjkim    }
664298714Sjkim
665298714Sjkim    return (Status);
666285728Sjkim}
667285728Sjkim#endif
668