xref: /illumos-gate/usr/src/common/acpica/utilities/utclib.c (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1 /******************************************************************************
2  *
3  * Module Name: utclib - ACPICA implementations of C library functions
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #define ACPI_CLIBRARY
153 #include "acpi.h"
154 #include "accommon.h"
155 
156 /*
157  * This module contains implementations of the standard C library functions
158  * that are required by the ACPICA code at both application level and kernel
159  * level.
160  *
161  * The module is an optional feature that can be used if a local/system
162  * C library is not available. Some operating system kernels may not have
163  * an internal C library.
164  *
165  * In general, these functions are less efficient than an inline or assembly
166  * code implementation.
167  *
168  * These C functions and the associated prototypes are enabled by default
169  * unless the ACPI_USE_SYSTEM_CLIBRARY symbol is defined. This is usually
170  * automatically defined for the ACPICA applications such as iASL and
171  * AcpiExec, so that these user-level applications use the local C library
172  * instead of the functions in this module.
173  */
174 
175 /*******************************************************************************
176  *
177  * Functions implemented in this module:
178  *
179  * FUNCTION:    memcmp
180  * FUNCTION:    memcpy
181  * FUNCTION:    memset
182  * FUNCTION:    strlen
183  * FUNCTION:    strcpy
184  * FUNCTION:    strncpy
185  * FUNCTION:    strcmp
186  * FUNCTION:    strchr
187  * FUNCTION:    strncmp
188  * FUNCTION:    strcat
189  * FUNCTION:    strncat
190  * FUNCTION:    strstr
191  * FUNCTION:    strtoul
192  * FUNCTION:    toupper
193  * FUNCTION:    tolower
194  * FUNCTION:    is* functions
195  *
196  ******************************************************************************/
197 
198 #define _COMPONENT          ACPI_UTILITIES
199         ACPI_MODULE_NAME    ("utclib")
200 
201 
202 #ifndef ACPI_USE_SYSTEM_CLIBRARY    /* Entire module */
203 
204 
205 /*******************************************************************************
206  *
207  * FUNCTION:    memcmp
208  *
209  * PARAMETERS:  Buffer1         - First Buffer
210  *              Buffer2         - Second Buffer
211  *              Count           - Maximum # of bytes to compare
212  *
213  * RETURN:      Index where Buffers mismatched, or 0 if Buffers matched
214  *
215  * DESCRIPTION: Compare two Buffers, with a maximum length
216  *
217  ******************************************************************************/
218 
219 int
220 memcmp (
221     void                    *VBuffer1,
222     void                    *VBuffer2,
223     ACPI_SIZE               Count)
224 {
225     char                    *Buffer1 = (char *) VBuffer1;
226     char                    *Buffer2 = (char *) VBuffer2;
227 
228 
229     for ( ; Count-- && (*Buffer1 == *Buffer2); Buffer1++, Buffer2++)
230     {
231     }
232 
233     return ((Count == ACPI_SIZE_MAX) ? 0 : ((unsigned char) *Buffer1 -
234         (unsigned char) *Buffer2));
235 }
236 
237 
238 /*******************************************************************************
239  *
240  * FUNCTION:    memmove
241  *
242  * PARAMETERS:  Dest        - Target of the copy
243  *              Src         - Source buffer to copy
244  *              Count       - Number of bytes to copy
245  *
246  * RETURN:      Dest
247  *
248  * DESCRIPTION: Copy arbitrary bytes of memory with respect to the overlapping
249  *
250  ******************************************************************************/
251 
252 void *
253 memmove (
254     void                    *Dest,
255     const void              *Src,
256     ACPI_SIZE               Count)
257 {
258     char                    *New = (char *) Dest;
259     char                    *Old = (char *) Src;
260 
261 
262     if (Old > New)
263     {
264         /* Copy from the beginning */
265 
266         while (Count)
267         {
268             *New = *Old;
269             New++;
270             Old++;
271             Count--;
272         }
273     }
274     else if (Old < New)
275     {
276         /* Copy from the end */
277 
278         New = New + Count - 1;
279         Old = Old + Count - 1;
280         while (Count)
281         {
282             *New = *Old;
283             New--;
284             Old--;
285             Count--;
286         }
287     }
288 
289     return (Dest);
290 }
291 
292 
293 /*******************************************************************************
294  *
295  * FUNCTION:    memcpy
296  *
297  * PARAMETERS:  Dest        - Target of the copy
298  *              Src         - Source buffer to copy
299  *              Count       - Number of bytes to copy
300  *
301  * RETURN:      Dest
302  *
303  * DESCRIPTION: Copy arbitrary bytes of memory
304  *
305  ******************************************************************************/
306 
307 void *
308 memcpy (
309     void                    *Dest,
310     const void              *Src,
311     ACPI_SIZE               Count)
312 {
313     char                    *New = (char *) Dest;
314     char                    *Old = (char *) Src;
315 
316 
317     while (Count)
318     {
319         *New = *Old;
320         New++;
321         Old++;
322         Count--;
323     }
324 
325     return (Dest);
326 }
327 
328 
329 /*******************************************************************************
330  *
331  * FUNCTION:    memset
332  *
333  * PARAMETERS:  Dest        - Buffer to set
334  *              Value       - Value to set each byte of memory
335  *              Count       - Number of bytes to set
336  *
337  * RETURN:      Dest
338  *
339  * DESCRIPTION: Initialize a buffer to a known value.
340  *
341  ******************************************************************************/
342 
343 void *
344 memset (
345     void                    *Dest,
346     int                     Value,
347     ACPI_SIZE               Count)
348 {
349     char                    *New = (char *) Dest;
350 
351 
352     while (Count)
353     {
354         *New = (char) Value;
355         New++;
356         Count--;
357     }
358 
359     return (Dest);
360 }
361 
362 
363 /*******************************************************************************
364  *
365  * FUNCTION:    strlen
366  *
367  * PARAMETERS:  String              - Null terminated string
368  *
369  * RETURN:      Length
370  *
371  * DESCRIPTION: Returns the length of the input string
372  *
373  ******************************************************************************/
374 
375 
376 ACPI_SIZE
377 strlen (
378     const char              *String)
379 {
380     UINT32                  Length = 0;
381 
382 
383     /* Count the string until a null is encountered */
384 
385     while (*String)
386     {
387         Length++;
388         String++;
389     }
390 
391     return (Length);
392 }
393 
394 
395 /*******************************************************************************
396  *
397  * FUNCTION:    strpbrk
398  *
399  * PARAMETERS:  String              - Null terminated string
400  *              Delimiters          - Delimiters to match
401  *
402  * RETURN:      The first occurance in the string of any of the bytes in the
403  *              delimiters
404  *
405  * DESCRIPTION: Search a string for any of a set of the delimiters
406  *
407  ******************************************************************************/
408 
409 char *
410 strpbrk (
411     const char              *String,
412     const char              *Delimiters)
413 {
414     const char              *Delimiter;
415 
416 
417     for ( ; *String != '\0'; ++String)
418     {
419         for (Delimiter = Delimiters; *Delimiter != '\0'; Delimiter++)
420         {
421             if (*String == *Delimiter)
422             {
423                 return (ACPI_CAST_PTR (char, String));
424             }
425         }
426     }
427 
428     return (NULL);
429 }
430 
431 
432 /*******************************************************************************
433  *
434  * FUNCTION:    strtok
435  *
436  * PARAMETERS:  String              - Null terminated string
437  *              Delimiters          - Delimiters to match
438  *
439  * RETURN:      Pointer to the next token
440  *
441  * DESCRIPTION: Split string into tokens
442  *
443  ******************************************************************************/
444 
445 char*
446 strtok (
447     char                    *String,
448     const char              *Delimiters)
449 {
450     char                    *Begin = String;
451     static char             *SavedPtr;
452 
453 
454     if (Begin == NULL)
455     {
456         if (SavedPtr == NULL)
457         {
458             return (NULL);
459         }
460         Begin = SavedPtr;
461     }
462 
463     SavedPtr = strpbrk (Begin, Delimiters);
464     while (SavedPtr == Begin)
465     {
466         *Begin++ = '\0';
467         SavedPtr = strpbrk (Begin, Delimiters);
468     }
469 
470     if (SavedPtr)
471     {
472         *SavedPtr++ = '\0';
473         return (Begin);
474     }
475     else
476     {
477         return (NULL);
478     }
479 }
480 
481 
482 /*******************************************************************************
483  *
484  * FUNCTION:    strcpy
485  *
486  * PARAMETERS:  DstString       - Target of the copy
487  *              SrcString       - The source string to copy
488  *
489  * RETURN:      DstString
490  *
491  * DESCRIPTION: Copy a null terminated string
492  *
493  ******************************************************************************/
494 
495 char *
496 strcpy (
497     char                    *DstString,
498     const char              *SrcString)
499 {
500     char                    *String = DstString;
501 
502 
503     /* Move bytes brute force */
504 
505     while (*SrcString)
506     {
507         *String = *SrcString;
508 
509         String++;
510         SrcString++;
511     }
512 
513     /* Null terminate */
514 
515     *String = 0;
516     return (DstString);
517 }
518 
519 
520 /*******************************************************************************
521  *
522  * FUNCTION:    strncpy
523  *
524  * PARAMETERS:  DstString       - Target of the copy
525  *              SrcString       - The source string to copy
526  *              Count           - Maximum # of bytes to copy
527  *
528  * RETURN:      DstString
529  *
530  * DESCRIPTION: Copy a null terminated string, with a maximum length
531  *
532  ******************************************************************************/
533 
534 char *
535 strncpy (
536     char                    *DstString,
537     const char              *SrcString,
538     ACPI_SIZE               Count)
539 {
540     char                    *String = DstString;
541 
542 
543     /* Copy the string */
544 
545     for (String = DstString;
546         Count && (Count--, (*String++ = *SrcString++)); )
547     {;}
548 
549     /* Pad with nulls if necessary */
550 
551     while (Count--)
552     {
553         *String = 0;
554         String++;
555     }
556 
557     /* Return original pointer */
558 
559     return (DstString);
560 }
561 
562 
563 /*******************************************************************************
564  *
565  * FUNCTION:    strcmp
566  *
567  * PARAMETERS:  String1         - First string
568  *              String2         - Second string
569  *
570  * RETURN:      Index where strings mismatched, or 0 if strings matched
571  *
572  * DESCRIPTION: Compare two null terminated strings
573  *
574  ******************************************************************************/
575 
576 int
577 strcmp (
578     const char              *String1,
579     const char              *String2)
580 {
581 
582 
583     for ( ; (*String1 == *String2); String2++)
584     {
585         if (!*String1++)
586         {
587             return (0);
588         }
589     }
590 
591     return ((unsigned char) *String1 - (unsigned char) *String2);
592 }
593 
594 
595 /*******************************************************************************
596  *
597  * FUNCTION:    strchr
598  *
599  * PARAMETERS:  String          - Search string
600  *              ch              - character to search for
601  *
602  * RETURN:      Ptr to char or NULL if not found
603  *
604  * DESCRIPTION: Search a string for a character
605  *
606  ******************************************************************************/
607 
608 char *
609 strchr (
610     const char              *String,
611     int                     ch)
612 {
613 
614 
615     for ( ; (*String); String++)
616     {
617         if ((*String) == (char) ch)
618         {
619             return ((char *) String);
620         }
621     }
622 
623     return (NULL);
624 }
625 
626 
627 /*******************************************************************************
628  *
629  * FUNCTION:    strncmp
630  *
631  * PARAMETERS:  String1         - First string
632  *              String2         - Second string
633  *              Count           - Maximum # of bytes to compare
634  *
635  * RETURN:      Index where strings mismatched, or 0 if strings matched
636  *
637  * DESCRIPTION: Compare two null terminated strings, with a maximum length
638  *
639  ******************************************************************************/
640 
641 int
642 strncmp (
643     const char              *String1,
644     const char              *String2,
645     ACPI_SIZE               Count)
646 {
647 
648 
649     for ( ; Count-- && (*String1 == *String2); String2++)
650     {
651         if (!*String1++)
652         {
653             return (0);
654         }
655     }
656 
657     return ((Count == ACPI_SIZE_MAX) ? 0 : ((unsigned char) *String1 -
658         (unsigned char) *String2));
659 }
660 
661 
662 /*******************************************************************************
663  *
664  * FUNCTION:    strcat
665  *
666  * PARAMETERS:  DstString       - Target of the copy
667  *              SrcString       - The source string to copy
668  *
669  * RETURN:      DstString
670  *
671  * DESCRIPTION: Append a null terminated string to a null terminated string
672  *
673  ******************************************************************************/
674 
675 char *
676 strcat (
677     char                    *DstString,
678     const char              *SrcString)
679 {
680     char                    *String;
681 
682 
683     /* Find end of the destination string */
684 
685     for (String = DstString; *String++; )
686     { ; }
687 
688     /* Concatenate the string */
689 
690     for (--String; (*String++ = *SrcString++); )
691     { ; }
692 
693     return (DstString);
694 }
695 
696 
697 /*******************************************************************************
698  *
699  * FUNCTION:    strncat
700  *
701  * PARAMETERS:  DstString       - Target of the copy
702  *              SrcString       - The source string to copy
703  *              Count           - Maximum # of bytes to copy
704  *
705  * RETURN:      DstString
706  *
707  * DESCRIPTION: Append a null terminated string to a null terminated string,
708  *              with a maximum count.
709  *
710  ******************************************************************************/
711 
712 char *
713 strncat (
714     char                    *DstString,
715     const char              *SrcString,
716     ACPI_SIZE               Count)
717 {
718     char                    *String;
719 
720 
721     if (Count)
722     {
723         /* Find end of the destination string */
724 
725         for (String = DstString; *String++; )
726         { ; }
727 
728         /* Concatenate the string */
729 
730         for (--String; (*String++ = *SrcString++) && --Count; )
731         { ; }
732 
733         /* Null terminate if necessary */
734 
735         if (!Count)
736         {
737             *String = 0;
738         }
739     }
740 
741     return (DstString);
742 }
743 
744 
745 /*******************************************************************************
746  *
747  * FUNCTION:    strstr
748  *
749  * PARAMETERS:  String1         - Target string
750  *              String2         - Substring to search for
751  *
752  * RETURN:      Where substring match starts, Null if no match found
753  *
754  * DESCRIPTION: Checks if String2 occurs in String1. This is not really a
755  *              full implementation of strstr, only sufficient for command
756  *              matching
757  *
758  ******************************************************************************/
759 
760 char *
761 strstr (
762     char                    *String1,
763     char                    *String2)
764 {
765     ACPI_SIZE               Length;
766 
767 
768     Length = strlen (String2);
769     if (!Length)
770     {
771         return (String1);
772     }
773 
774     while (strlen (String1) >= Length)
775     {
776         if (memcmp (String1, String2, Length) == 0)
777         {
778             return (String1);
779         }
780         String1++;
781     }
782 
783     return (NULL);
784 }
785 
786 
787 /*******************************************************************************
788  *
789  * FUNCTION:    strtoul
790  *
791  * PARAMETERS:  String          - Null terminated string
792  *              Terminater      - Where a pointer to the terminating byte is
793  *                                returned
794  *              Base            - Radix of the string
795  *
796  * RETURN:      Converted value
797  *
798  * DESCRIPTION: Convert a string into a 32-bit unsigned value.
799  *              Note: use strtoul64 for 64-bit integers.
800  *
801  ******************************************************************************/
802 
803 UINT32
804 strtoul (
805     const char              *String,
806     char                    **Terminator,
807     UINT32                  Base)
808 {
809     UINT32                  converted = 0;
810     UINT32                  index;
811     UINT32                  sign;
812     const char              *StringStart;
813     UINT32                  ReturnValue = 0;
814     ACPI_STATUS             Status = AE_OK;
815 
816 
817     /*
818      * Save the value of the pointer to the buffer's first
819      * character, save the current errno value, and then
820      * skip over any white space in the buffer:
821      */
822     StringStart = String;
823     while (isspace (*String) || *String == '\t')
824     {
825         ++String;
826     }
827 
828     /*
829      * The buffer may contain an optional plus or minus sign.
830      * If it does, then skip over it but remember what is was:
831      */
832     if (*String == '-')
833     {
834         sign = ACPI_SIGN_NEGATIVE;
835         ++String;
836     }
837     else if (*String == '+')
838     {
839         ++String;
840         sign = ACPI_SIGN_POSITIVE;
841     }
842     else
843     {
844         sign = ACPI_SIGN_POSITIVE;
845     }
846 
847     /*
848      * If the input parameter Base is zero, then we need to
849      * determine if it is octal, decimal, or hexadecimal:
850      */
851     if (Base == 0)
852     {
853         if (*String == '0')
854         {
855             if (tolower (*(++String)) == 'x')
856             {
857                 Base = 16;
858                 ++String;
859             }
860             else
861             {
862                 Base = 8;
863             }
864         }
865         else
866         {
867             Base = 10;
868         }
869     }
870     else if (Base < 2 || Base > 36)
871     {
872         /*
873          * The specified Base parameter is not in the domain of
874          * this function:
875          */
876         goto done;
877     }
878 
879     /*
880      * For octal and hexadecimal bases, skip over the leading
881      * 0 or 0x, if they are present.
882      */
883     if (Base == 8 && *String == '0')
884     {
885         String++;
886     }
887 
888     if (Base == 16 &&
889         *String == '0' &&
890         tolower (*(++String)) == 'x')
891     {
892         String++;
893     }
894 
895     /*
896      * Main loop: convert the string to an unsigned long:
897      */
898     while (*String)
899     {
900         if (isdigit (*String))
901         {
902             index = (UINT32) ((UINT8) *String - '0');
903         }
904         else
905         {
906             index = (UINT32) toupper (*String);
907             if (isupper (index))
908             {
909                 index = index - 'A' + 10;
910             }
911             else
912             {
913                 goto done;
914             }
915         }
916 
917         if (index >= Base)
918         {
919             goto done;
920         }
921 
922         /*
923          * Check to see if value is out of range:
924          */
925 
926         if (ReturnValue > ((ACPI_UINT32_MAX - (UINT32) index) /
927                             (UINT32) Base))
928         {
929             Status = AE_ERROR;
930             ReturnValue = 0;           /* reset */
931         }
932         else
933         {
934             ReturnValue *= Base;
935             ReturnValue += index;
936             converted = 1;
937         }
938 
939         ++String;
940     }
941 
942 done:
943     /*
944      * If appropriate, update the caller's pointer to the next
945      * unconverted character in the buffer.
946      */
947     if (Terminator)
948     {
949         if (converted == 0 && ReturnValue == 0 && String != NULL)
950         {
951             *Terminator = (char *) StringStart;
952         }
953         else
954         {
955             *Terminator = (char *) String;
956         }
957     }
958 
959     if (Status == AE_ERROR)
960     {
961         ReturnValue = ACPI_UINT32_MAX;
962     }
963 
964     /*
965      * If a minus sign was present, then "the conversion is negated":
966      */
967     if (sign == ACPI_SIGN_NEGATIVE)
968     {
969         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
970     }
971 
972     return (ReturnValue);
973 }
974 
975 
976 /*******************************************************************************
977  *
978  * FUNCTION:    toupper
979  *
980  * PARAMETERS:  c           - Character to convert
981  *
982  * RETURN:      Converted character as an int
983  *
984  * DESCRIPTION: Convert character to uppercase
985  *
986  ******************************************************************************/
987 
988 int
989 toupper (
990     int                     c)
991 {
992 
993     return (islower(c) ? ((c)-0x20) : (c));
994 }
995 
996 
997 /*******************************************************************************
998  *
999  * FUNCTION:    tolower
1000  *
1001  * PARAMETERS:  c           - Character to convert
1002  *
1003  * RETURN:      Converted character as an int
1004  *
1005  * DESCRIPTION: Convert character to lowercase
1006  *
1007  ******************************************************************************/
1008 
1009 int
1010 tolower (
1011     int                     c)
1012 {
1013 
1014     return (isupper(c) ? ((c)+0x20) : (c));
1015 }
1016 
1017 
1018 /*******************************************************************************
1019  *
1020  * FUNCTION:    is* function array
1021  *
1022  * DESCRIPTION: is* functions use the ctype table below
1023  *
1024  ******************************************************************************/
1025 
1026 const UINT8 AcpiGbl_Ctypes[257] = {
1027     _ACPI_CN,            /* 0x00     0 NUL */
1028     _ACPI_CN,            /* 0x01     1 SOH */
1029     _ACPI_CN,            /* 0x02     2 STX */
1030     _ACPI_CN,            /* 0x03     3 ETX */
1031     _ACPI_CN,            /* 0x04     4 EOT */
1032     _ACPI_CN,            /* 0x05     5 ENQ */
1033     _ACPI_CN,            /* 0x06     6 ACK */
1034     _ACPI_CN,            /* 0x07     7 BEL */
1035     _ACPI_CN,            /* 0x08     8 BS  */
1036     _ACPI_CN|_ACPI_SP,   /* 0x09     9 TAB */
1037     _ACPI_CN|_ACPI_SP,   /* 0x0A    10 LF  */
1038     _ACPI_CN|_ACPI_SP,   /* 0x0B    11 VT  */
1039     _ACPI_CN|_ACPI_SP,   /* 0x0C    12 FF  */
1040     _ACPI_CN|_ACPI_SP,   /* 0x0D    13 CR  */
1041     _ACPI_CN,            /* 0x0E    14 SO  */
1042     _ACPI_CN,            /* 0x0F    15 SI  */
1043     _ACPI_CN,            /* 0x10    16 DLE */
1044     _ACPI_CN,            /* 0x11    17 DC1 */
1045     _ACPI_CN,            /* 0x12    18 DC2 */
1046     _ACPI_CN,            /* 0x13    19 DC3 */
1047     _ACPI_CN,            /* 0x14    20 DC4 */
1048     _ACPI_CN,            /* 0x15    21 NAK */
1049     _ACPI_CN,            /* 0x16    22 SYN */
1050     _ACPI_CN,            /* 0x17    23 ETB */
1051     _ACPI_CN,            /* 0x18    24 CAN */
1052     _ACPI_CN,            /* 0x19    25 EM  */
1053     _ACPI_CN,            /* 0x1A    26 SUB */
1054     _ACPI_CN,            /* 0x1B    27 ESC */
1055     _ACPI_CN,            /* 0x1C    28 FS  */
1056     _ACPI_CN,            /* 0x1D    29 GS  */
1057     _ACPI_CN,            /* 0x1E    30 RS  */
1058     _ACPI_CN,            /* 0x1F    31 US  */
1059     _ACPI_XS|_ACPI_SP,   /* 0x20    32 ' ' */
1060     _ACPI_PU,            /* 0x21    33 '!' */
1061     _ACPI_PU,            /* 0x22    34 '"' */
1062     _ACPI_PU,            /* 0x23    35 '#' */
1063     _ACPI_PU,            /* 0x24    36 '$' */
1064     _ACPI_PU,            /* 0x25    37 '%' */
1065     _ACPI_PU,            /* 0x26    38 '&' */
1066     _ACPI_PU,            /* 0x27    39 ''' */
1067     _ACPI_PU,            /* 0x28    40 '(' */
1068     _ACPI_PU,            /* 0x29    41 ')' */
1069     _ACPI_PU,            /* 0x2A    42 '*' */
1070     _ACPI_PU,            /* 0x2B    43 '+' */
1071     _ACPI_PU,            /* 0x2C    44 ',' */
1072     _ACPI_PU,            /* 0x2D    45 '-' */
1073     _ACPI_PU,            /* 0x2E    46 '.' */
1074     _ACPI_PU,            /* 0x2F    47 '/' */
1075     _ACPI_XD|_ACPI_DI,   /* 0x30    48 '0' */
1076     _ACPI_XD|_ACPI_DI,   /* 0x31    49 '1' */
1077     _ACPI_XD|_ACPI_DI,   /* 0x32    50 '2' */
1078     _ACPI_XD|_ACPI_DI,   /* 0x33    51 '3' */
1079     _ACPI_XD|_ACPI_DI,   /* 0x34    52 '4' */
1080     _ACPI_XD|_ACPI_DI,   /* 0x35    53 '5' */
1081     _ACPI_XD|_ACPI_DI,   /* 0x36    54 '6' */
1082     _ACPI_XD|_ACPI_DI,   /* 0x37    55 '7' */
1083     _ACPI_XD|_ACPI_DI,   /* 0x38    56 '8' */
1084     _ACPI_XD|_ACPI_DI,   /* 0x39    57 '9' */
1085     _ACPI_PU,            /* 0x3A    58 ':' */
1086     _ACPI_PU,            /* 0x3B    59 ';' */
1087     _ACPI_PU,            /* 0x3C    60 '<' */
1088     _ACPI_PU,            /* 0x3D    61 '=' */
1089     _ACPI_PU,            /* 0x3E    62 '>' */
1090     _ACPI_PU,            /* 0x3F    63 '?' */
1091     _ACPI_PU,            /* 0x40    64 '@' */
1092     _ACPI_XD|_ACPI_UP,   /* 0x41    65 'A' */
1093     _ACPI_XD|_ACPI_UP,   /* 0x42    66 'B' */
1094     _ACPI_XD|_ACPI_UP,   /* 0x43    67 'C' */
1095     _ACPI_XD|_ACPI_UP,   /* 0x44    68 'D' */
1096     _ACPI_XD|_ACPI_UP,   /* 0x45    69 'E' */
1097     _ACPI_XD|_ACPI_UP,   /* 0x46    70 'F' */
1098     _ACPI_UP,            /* 0x47    71 'G' */
1099     _ACPI_UP,            /* 0x48    72 'H' */
1100     _ACPI_UP,            /* 0x49    73 'I' */
1101     _ACPI_UP,            /* 0x4A    74 'J' */
1102     _ACPI_UP,            /* 0x4B    75 'K' */
1103     _ACPI_UP,            /* 0x4C    76 'L' */
1104     _ACPI_UP,            /* 0x4D    77 'M' */
1105     _ACPI_UP,            /* 0x4E    78 'N' */
1106     _ACPI_UP,            /* 0x4F    79 'O' */
1107     _ACPI_UP,            /* 0x50    80 'P' */
1108     _ACPI_UP,            /* 0x51    81 'Q' */
1109     _ACPI_UP,            /* 0x52    82 'R' */
1110     _ACPI_UP,            /* 0x53    83 'S' */
1111     _ACPI_UP,            /* 0x54    84 'T' */
1112     _ACPI_UP,            /* 0x55    85 'U' */
1113     _ACPI_UP,            /* 0x56    86 'V' */
1114     _ACPI_UP,            /* 0x57    87 'W' */
1115     _ACPI_UP,            /* 0x58    88 'X' */
1116     _ACPI_UP,            /* 0x59    89 'Y' */
1117     _ACPI_UP,            /* 0x5A    90 'Z' */
1118     _ACPI_PU,            /* 0x5B    91 '[' */
1119     _ACPI_PU,            /* 0x5C    92 '\' */
1120     _ACPI_PU,            /* 0x5D    93 ']' */
1121     _ACPI_PU,            /* 0x5E    94 '^' */
1122     _ACPI_PU,            /* 0x5F    95 '_' */
1123     _ACPI_PU,            /* 0x60    96 '`' */
1124     _ACPI_XD|_ACPI_LO,   /* 0x61    97 'a' */
1125     _ACPI_XD|_ACPI_LO,   /* 0x62    98 'b' */
1126     _ACPI_XD|_ACPI_LO,   /* 0x63    99 'c' */
1127     _ACPI_XD|_ACPI_LO,   /* 0x64   100 'd' */
1128     _ACPI_XD|_ACPI_LO,   /* 0x65   101 'e' */
1129     _ACPI_XD|_ACPI_LO,   /* 0x66   102 'f' */
1130     _ACPI_LO,            /* 0x67   103 'g' */
1131     _ACPI_LO,            /* 0x68   104 'h' */
1132     _ACPI_LO,            /* 0x69   105 'i' */
1133     _ACPI_LO,            /* 0x6A   106 'j' */
1134     _ACPI_LO,            /* 0x6B   107 'k' */
1135     _ACPI_LO,            /* 0x6C   108 'l' */
1136     _ACPI_LO,            /* 0x6D   109 'm' */
1137     _ACPI_LO,            /* 0x6E   110 'n' */
1138     _ACPI_LO,            /* 0x6F   111 'o' */
1139     _ACPI_LO,            /* 0x70   112 'p' */
1140     _ACPI_LO,            /* 0x71   113 'q' */
1141     _ACPI_LO,            /* 0x72   114 'r' */
1142     _ACPI_LO,            /* 0x73   115 's' */
1143     _ACPI_LO,            /* 0x74   116 't' */
1144     _ACPI_LO,            /* 0x75   117 'u' */
1145     _ACPI_LO,            /* 0x76   118 'v' */
1146     _ACPI_LO,            /* 0x77   119 'w' */
1147     _ACPI_LO,            /* 0x78   120 'x' */
1148     _ACPI_LO,            /* 0x79   121 'y' */
1149     _ACPI_LO,            /* 0x7A   122 'z' */
1150     _ACPI_PU,            /* 0x7B   123 '{' */
1151     _ACPI_PU,            /* 0x7C   124 '|' */
1152     _ACPI_PU,            /* 0x7D   125 '}' */
1153     _ACPI_PU,            /* 0x7E   126 '~' */
1154     _ACPI_CN,            /* 0x7F   127 DEL */
1155 
1156     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0x80 to 0x8F    */
1157     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0x90 to 0x9F    */
1158     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xA0 to 0xAF    */
1159     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xB0 to 0xBF    */
1160     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xC0 to 0xCF    */
1161     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xD0 to 0xDF    */
1162     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xE0 to 0xEF    */
1163     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xF0 to 0xFF    */
1164     0                                 /* 0x100 */
1165 };
1166 
1167 
1168 #endif /* ACPI_USE_SYSTEM_CLIBRARY */
1169