1285728Sjkim/*******************************************************************************
2285728Sjkim *
3285728Sjkim * Module Name: utnonansi - Non-ansi C library functions
4285728Sjkim *
5285728Sjkim ******************************************************************************/
6285728Sjkim
7285728Sjkim/*
8306536Sjkim * 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
167306536Sjkim#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
168285728Sjkim/*******************************************************************************
169285728Sjkim *
170306536Sjkim * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
171306536Sjkim *
172306536Sjkim * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
173306536Sjkim *              functions. This is the size of the Destination buffer.
174306536Sjkim *
175306536Sjkim * RETURN:      TRUE if the operation would overflow the destination buffer.
176306536Sjkim *
177306536Sjkim * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
178306536Sjkim *              the result of the operation will not overflow the output string
179306536Sjkim *              buffer.
180306536Sjkim *
181306536Sjkim * NOTE:        These functions are typically only helpful for processing
182306536Sjkim *              user input and command lines. For most ACPICA code, the
183306536Sjkim *              required buffer length is precisely calculated before buffer
184306536Sjkim *              allocation, so the use of these functions is unnecessary.
185306536Sjkim *
186306536Sjkim ******************************************************************************/
187306536Sjkim
188306536SjkimBOOLEAN
189306536SjkimAcpiUtSafeStrcpy (
190306536Sjkim    char                    *Dest,
191306536Sjkim    ACPI_SIZE               DestSize,
192306536Sjkim    char                    *Source)
193306536Sjkim{
194306536Sjkim
195306536Sjkim    if (strlen (Source) >= DestSize)
196306536Sjkim    {
197306536Sjkim        return (TRUE);
198306536Sjkim    }
199306536Sjkim
200306536Sjkim    strcpy (Dest, Source);
201306536Sjkim    return (FALSE);
202306536Sjkim}
203306536Sjkim
204306536SjkimBOOLEAN
205306536SjkimAcpiUtSafeStrcat (
206306536Sjkim    char                    *Dest,
207306536Sjkim    ACPI_SIZE               DestSize,
208306536Sjkim    char                    *Source)
209306536Sjkim{
210306536Sjkim
211306536Sjkim    if ((strlen (Dest) + strlen (Source)) >= DestSize)
212306536Sjkim    {
213306536Sjkim        return (TRUE);
214306536Sjkim    }
215306536Sjkim
216306536Sjkim    strcat (Dest, Source);
217306536Sjkim    return (FALSE);
218306536Sjkim}
219306536Sjkim
220306536SjkimBOOLEAN
221306536SjkimAcpiUtSafeStrncat (
222306536Sjkim    char                    *Dest,
223306536Sjkim    ACPI_SIZE               DestSize,
224306536Sjkim    char                    *Source,
225306536Sjkim    ACPI_SIZE               MaxTransferLength)
226306536Sjkim{
227306536Sjkim    ACPI_SIZE               ActualTransferLength;
228306536Sjkim
229306536Sjkim
230306536Sjkim    ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
231306536Sjkim
232306536Sjkim    if ((strlen (Dest) + ActualTransferLength) >= DestSize)
233306536Sjkim    {
234306536Sjkim        return (TRUE);
235306536Sjkim    }
236306536Sjkim
237306536Sjkim    strncat (Dest, Source, MaxTransferLength);
238306536Sjkim    return (FALSE);
239306536Sjkim}
240306536Sjkim#endif
241306536Sjkim
242306536Sjkim
243306536Sjkim/*******************************************************************************
244306536Sjkim *
245285728Sjkim * FUNCTION:    AcpiUtStrtoul64
246285728Sjkim *
247306536Sjkim * PARAMETERS:  String                  - Null terminated string
248306536Sjkim *              Base                    - Radix of the string: 16 or 10 or
249306536Sjkim *                                        ACPI_ANY_BASE
250306536Sjkim *              MaxIntegerByteWidth     - Maximum allowable integer,in bytes:
251306536Sjkim *                                        4 or 8 (32 or 64 bits)
252306536Sjkim *              RetInteger              - Where the converted integer is
253306536Sjkim *                                        returned
254285728Sjkim *
255285728Sjkim * RETURN:      Status and Converted value
256285728Sjkim *
257285728Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a
258306536Sjkim *              32-bit or 64-bit conversion, depending on the input integer
259306536Sjkim *              size (often the current mode of the interpreter).
260285728Sjkim *
261306536Sjkim * NOTES:       Negative numbers are not supported, as they are not supported
262306536Sjkim *              by ACPI.
263285728Sjkim *
264306536Sjkim *              AcpiGbl_IntegerByteWidth should be set to the proper width.
265306536Sjkim *              For the core ACPICA code, this width depends on the DSDT
266306536Sjkim *              version. For iASL, the default byte width is always 8 for the
267306536Sjkim *              parser, but error checking is performed later to flag cases
268306536Sjkim *              where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
269306536Sjkim *
270306536Sjkim *              Does not support Octal strings, not needed at this time.
271306536Sjkim *
272285728Sjkim ******************************************************************************/
273285728Sjkim
274285728SjkimACPI_STATUS
275285728SjkimAcpiUtStrtoul64 (
276285728Sjkim    char                    *String,
277285728Sjkim    UINT32                  Base,
278306536Sjkim    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
290306536Sjkim    ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
291285728Sjkim
292285728Sjkim
293285728Sjkim    switch (Base)
294285728Sjkim    {
295285728Sjkim    case ACPI_ANY_BASE:
296306536Sjkim    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
320306536Sjkim    if (Base == ACPI_ANY_BASE)
321285728Sjkim    {
322285728Sjkim        /*
323306536Sjkim         * 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    {
344306536Sjkim        if (Base == ACPI_ANY_BASE)
345285728Sjkim        {
346285728Sjkim            goto ErrorExit;
347285728Sjkim        }
348285728Sjkim        else
349285728Sjkim        {
350285728Sjkim            goto AllDone;
351285728Sjkim        }
352285728Sjkim    }
353285728Sjkim
354285728Sjkim    /*
355306536Sjkim     * Perform a 32-bit or 64-bit conversion, depending upon the input
356306536Sjkim     * byte width
357285728Sjkim     */
358306536Sjkim    Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ?
359306536Sjkim        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        {
394306536Sjkim            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
412306536Sjkim        if (SignOf0x && ((ValidDigits > 16) ||
413306536Sjkim            ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH))))
414285728Sjkim        {
415285728Sjkim            /*
416285728Sjkim             * This is ToInteger operation case.
417306536Sjkim             * 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
425306536Sjkim        (void) AcpiUtShortDivide (
426306536Sjkim            (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL);
427285728Sjkim
428285728Sjkim        if (ReturnValue > Quotient)
429285728Sjkim        {
430306536Sjkim            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
458306536Sjkim    /* Base was set/validated above (10 or 16) */
459306536Sjkim
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
471306536Sjkim#ifdef _OBSOLETE_FUNCTIONS
472306536Sjkim/* Removed: 01/2016 */
473306536Sjkim
474285728Sjkim/*******************************************************************************
475285728Sjkim *
476306536Sjkim * FUNCTION:    strtoul64
477285728Sjkim *
478306536Sjkim * PARAMETERS:  String              - Null terminated string
479306536Sjkim *              Terminater          - Where a pointer to the terminating byte
480306536Sjkim *                                    is returned
481306536Sjkim *              Base                - Radix of the string
482285728Sjkim *
483306536Sjkim * RETURN:      Converted value
484285728Sjkim *
485306536Sjkim * DESCRIPTION: Convert a string into an unsigned value.
486285728Sjkim *
487285728Sjkim ******************************************************************************/
488285728Sjkim
489306536SjkimACPI_STATUS
490306536Sjkimstrtoul64 (
491306536Sjkim    char                    *String,
492306536Sjkim    UINT32                  Base,
493306536Sjkim    UINT64                  *RetInteger)
494285728Sjkim{
495306536Sjkim    UINT32                  Index;
496306536Sjkim    UINT32                  Sign;
497306536Sjkim    UINT64                  ReturnValue = 0;
498306536Sjkim    ACPI_STATUS             Status = AE_OK;
499285728Sjkim
500306536Sjkim
501306536Sjkim    *RetInteger = 0;
502306536Sjkim
503306536Sjkim    switch (Base)
504285728Sjkim    {
505306536Sjkim    case 0:
506306536Sjkim    case 8:
507306536Sjkim    case 10:
508306536Sjkim    case 16:
509306536Sjkim
510306536Sjkim        break;
511306536Sjkim
512306536Sjkim    default:
513306536Sjkim        /*
514306536Sjkim         * The specified Base parameter is not in the domain of
515306536Sjkim         * this function:
516306536Sjkim         */
517306536Sjkim        return (AE_BAD_PARAMETER);
518285728Sjkim    }
519285728Sjkim
520306536Sjkim    /* Skip over any white space in the buffer: */
521285728Sjkim
522306536Sjkim    while (isspace ((int) *String) || *String == '\t')
523306536Sjkim    {
524306536Sjkim        ++String;
525306536Sjkim    }
526285728Sjkim
527306536Sjkim    /*
528306536Sjkim     * The buffer may contain an optional plus or minus sign.
529306536Sjkim     * If it does, then skip over it but remember what is was:
530306536Sjkim     */
531306536Sjkim    if (*String == '-')
532285728Sjkim    {
533306536Sjkim        Sign = ACPI_SIGN_NEGATIVE;
534306536Sjkim        ++String;
535285728Sjkim    }
536306536Sjkim    else if (*String == '+')
537306536Sjkim    {
538306536Sjkim        ++String;
539306536Sjkim        Sign = ACPI_SIGN_POSITIVE;
540306536Sjkim    }
541306536Sjkim    else
542306536Sjkim    {
543306536Sjkim        Sign = ACPI_SIGN_POSITIVE;
544306536Sjkim    }
545285728Sjkim
546306536Sjkim    /*
547306536Sjkim     * If the input parameter Base is zero, then we need to
548306536Sjkim     * determine if it is octal, decimal, or hexadecimal:
549306536Sjkim     */
550306536Sjkim    if (Base == 0)
551306536Sjkim    {
552306536Sjkim        if (*String == '0')
553306536Sjkim        {
554306536Sjkim            if (tolower ((int) *(++String)) == 'x')
555306536Sjkim            {
556306536Sjkim                Base = 16;
557306536Sjkim                ++String;
558306536Sjkim            }
559306536Sjkim            else
560306536Sjkim            {
561306536Sjkim                Base = 8;
562306536Sjkim            }
563306536Sjkim        }
564306536Sjkim        else
565306536Sjkim        {
566306536Sjkim            Base = 10;
567306536Sjkim        }
568306536Sjkim    }
569285728Sjkim
570306536Sjkim    /*
571306536Sjkim     * For octal and hexadecimal bases, skip over the leading
572306536Sjkim     * 0 or 0x, if they are present.
573306536Sjkim     */
574306536Sjkim    if (Base == 8 && *String == '0')
575306536Sjkim    {
576306536Sjkim        String++;
577306536Sjkim    }
578285728Sjkim
579306536Sjkim    if (Base == 16 &&
580306536Sjkim        *String == '0' &&
581306536Sjkim        tolower ((int) *(++String)) == 'x')
582306536Sjkim    {
583306536Sjkim        String++;
584306536Sjkim    }
585285728Sjkim
586306536Sjkim    /* Main loop: convert the string to an unsigned long */
587285728Sjkim
588306536Sjkim    while (*String)
589285728Sjkim    {
590306536Sjkim        if (isdigit ((int) *String))
591306536Sjkim        {
592306536Sjkim            Index = ((UINT8) *String) - '0';
593306536Sjkim        }
594306536Sjkim        else
595306536Sjkim        {
596306536Sjkim            Index = (UINT8) toupper ((int) *String);
597306536Sjkim            if (isupper ((int) Index))
598306536Sjkim            {
599306536Sjkim                Index = Index - 'A' + 10;
600306536Sjkim            }
601306536Sjkim            else
602306536Sjkim            {
603306536Sjkim                goto ErrorExit;
604306536Sjkim            }
605306536Sjkim        }
606306536Sjkim
607306536Sjkim        if (Index >= Base)
608306536Sjkim        {
609306536Sjkim            goto ErrorExit;
610306536Sjkim        }
611306536Sjkim
612306536Sjkim        /* Check to see if value is out of range: */
613306536Sjkim
614306536Sjkim        if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
615306536Sjkim            (UINT64) Base))
616306536Sjkim        {
617306536Sjkim            goto ErrorExit;
618306536Sjkim        }
619306536Sjkim        else
620306536Sjkim        {
621306536Sjkim            ReturnValue *= Base;
622306536Sjkim            ReturnValue += Index;
623306536Sjkim        }
624306536Sjkim
625306536Sjkim        ++String;
626285728Sjkim    }
627285728Sjkim
628306536Sjkim
629306536Sjkim    /* If a minus sign was present, then "the conversion is negated": */
630306536Sjkim
631306536Sjkim    if (Sign == ACPI_SIGN_NEGATIVE)
632306536Sjkim    {
633306536Sjkim        ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
634306536Sjkim    }
635306536Sjkim
636306536Sjkim    *RetInteger = ReturnValue;
637306536Sjkim    return (Status);
638306536Sjkim
639306536Sjkim
640306536SjkimErrorExit:
641306536Sjkim    switch (Base)
642306536Sjkim    {
643306536Sjkim    case 8:
644306536Sjkim
645306536Sjkim        Status = AE_BAD_OCTAL_CONSTANT;
646306536Sjkim        break;
647306536Sjkim
648306536Sjkim    case 10:
649306536Sjkim
650306536Sjkim        Status = AE_BAD_DECIMAL_CONSTANT;
651306536Sjkim        break;
652306536Sjkim
653306536Sjkim    case 16:
654306536Sjkim
655306536Sjkim        Status = AE_BAD_HEX_CONSTANT;
656306536Sjkim        break;
657306536Sjkim
658306536Sjkim    default:
659306536Sjkim
660306536Sjkim        /* Base validated above */
661306536Sjkim
662306536Sjkim        break;
663306536Sjkim    }
664306536Sjkim
665306536Sjkim    return (Status);
666285728Sjkim}
667285728Sjkim#endif
668