xref: /titanic_50/usr/src/cmd/acpi/common/utnonansi.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1 /*******************************************************************************
2  *
3  * Module Name: utnonansi - Non-ansi C library functions
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 
47 
48 #define _COMPONENT          ACPI_UTILITIES
49         ACPI_MODULE_NAME    ("utnonansi")
50 
51 
52 /*
53  * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
54  * version of strtoul.
55  */
56 
57 /*******************************************************************************
58  *
59  * FUNCTION:    AcpiUtStrlwr (strlwr)
60  *
61  * PARAMETERS:  SrcString       - The source string to convert
62  *
63  * RETURN:      None
64  *
65  * DESCRIPTION: Convert a string to lowercase
66  *
67  ******************************************************************************/
68 
69 void
AcpiUtStrlwr(char * SrcString)70 AcpiUtStrlwr (
71     char                    *SrcString)
72 {
73     char                    *String;
74 
75 
76     ACPI_FUNCTION_ENTRY ();
77 
78 
79     if (!SrcString)
80     {
81         return;
82     }
83 
84     /* Walk entire string, lowercasing the letters */
85 
86     for (String = SrcString; *String; String++)
87     {
88         *String = (char) tolower ((int) *String);
89     }
90 }
91 
92 
93 /*******************************************************************************
94  *
95  * FUNCTION:    AcpiUtStrupr (strupr)
96  *
97  * PARAMETERS:  SrcString       - The source string to convert
98  *
99  * RETURN:      None
100  *
101  * DESCRIPTION: Convert a string to uppercase
102  *
103  ******************************************************************************/
104 
105 void
AcpiUtStrupr(char * SrcString)106 AcpiUtStrupr (
107     char                    *SrcString)
108 {
109     char                    *String;
110 
111 
112     ACPI_FUNCTION_ENTRY ();
113 
114 
115     if (!SrcString)
116     {
117         return;
118     }
119 
120     /* Walk entire string, uppercasing the letters */
121 
122     for (String = SrcString; *String; String++)
123     {
124         *String = (char) toupper ((int) *String);
125     }
126 }
127 
128 
129 /******************************************************************************
130  *
131  * FUNCTION:    AcpiUtStricmp (stricmp)
132  *
133  * PARAMETERS:  String1             - first string to compare
134  *              String2             - second string to compare
135  *
136  * RETURN:      int that signifies string relationship. Zero means strings
137  *              are equal.
138  *
139  * DESCRIPTION: Case-insensitive string compare. Implementation of the
140  *              non-ANSI stricmp function.
141  *
142  ******************************************************************************/
143 
144 int
AcpiUtStricmp(char * String1,char * String2)145 AcpiUtStricmp (
146     char                    *String1,
147     char                    *String2)
148 {
149     int                     c1;
150     int                     c2;
151 
152 
153     do
154     {
155         c1 = tolower ((int) *String1);
156         c2 = tolower ((int) *String2);
157 
158         String1++;
159         String2++;
160     }
161     while ((c1 == c2) && (c1));
162 
163     return (c1 - c2);
164 }
165 
166 
167 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
168 /*******************************************************************************
169  *
170  * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
171  *
172  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
173  *              functions. This is the size of the Destination buffer.
174  *
175  * RETURN:      TRUE if the operation would overflow the destination buffer.
176  *
177  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
178  *              the result of the operation will not overflow the output string
179  *              buffer.
180  *
181  * NOTE:        These functions are typically only helpful for processing
182  *              user input and command lines. For most ACPICA code, the
183  *              required buffer length is precisely calculated before buffer
184  *              allocation, so the use of these functions is unnecessary.
185  *
186  ******************************************************************************/
187 
188 BOOLEAN
AcpiUtSafeStrcpy(char * Dest,ACPI_SIZE DestSize,char * Source)189 AcpiUtSafeStrcpy (
190     char                    *Dest,
191     ACPI_SIZE               DestSize,
192     char                    *Source)
193 {
194 
195     if (strlen (Source) >= DestSize)
196     {
197         return (TRUE);
198     }
199 
200     strcpy (Dest, Source);
201     return (FALSE);
202 }
203 
204 BOOLEAN
AcpiUtSafeStrcat(char * Dest,ACPI_SIZE DestSize,char * Source)205 AcpiUtSafeStrcat (
206     char                    *Dest,
207     ACPI_SIZE               DestSize,
208     char                    *Source)
209 {
210 
211     if ((strlen (Dest) + strlen (Source)) >= DestSize)
212     {
213         return (TRUE);
214     }
215 
216     strcat (Dest, Source);
217     return (FALSE);
218 }
219 
220 BOOLEAN
AcpiUtSafeStrncat(char * Dest,ACPI_SIZE DestSize,char * Source,ACPI_SIZE MaxTransferLength)221 AcpiUtSafeStrncat (
222     char                    *Dest,
223     ACPI_SIZE               DestSize,
224     char                    *Source,
225     ACPI_SIZE               MaxTransferLength)
226 {
227     ACPI_SIZE               ActualTransferLength;
228 
229 
230     ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
231 
232     if ((strlen (Dest) + ActualTransferLength) >= DestSize)
233     {
234         return (TRUE);
235     }
236 
237     strncat (Dest, Source, MaxTransferLength);
238     return (FALSE);
239 }
240 #endif
241 
242 
243 /*******************************************************************************
244  *
245  * FUNCTION:    AcpiUtStrtoul64
246  *
247  * PARAMETERS:  String                  - Null terminated string
248  *              Base                    - Radix of the string: 16 or 10 or
249  *                                        ACPI_ANY_BASE
250  *              MaxIntegerByteWidth     - Maximum allowable integer,in bytes:
251  *                                        4 or 8 (32 or 64 bits)
252  *              RetInteger              - Where the converted integer is
253  *                                        returned
254  *
255  * RETURN:      Status and Converted value
256  *
257  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
258  *              32-bit or 64-bit conversion, depending on the input integer
259  *              size (often the current mode of the interpreter).
260  *
261  * NOTES:       Negative numbers are not supported, as they are not supported
262  *              by ACPI.
263  *
264  *              AcpiGbl_IntegerByteWidth should be set to the proper width.
265  *              For the core ACPICA code, this width depends on the DSDT
266  *              version. For iASL, the default byte width is always 8 for the
267  *              parser, but error checking is performed later to flag cases
268  *              where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
269  *
270  *              Does not support Octal strings, not needed at this time.
271  *
272  ******************************************************************************/
273 
274 ACPI_STATUS
AcpiUtStrtoul64(char * String,UINT32 Base,UINT32 MaxIntegerByteWidth,UINT64 * RetInteger)275 AcpiUtStrtoul64 (
276     char                    *String,
277     UINT32                  Base,
278     UINT32                  MaxIntegerByteWidth,
279     UINT64                  *RetInteger)
280 {
281     UINT32                  ThisDigit = 0;
282     UINT64                  ReturnValue = 0;
283     UINT64                  Quotient;
284     UINT64                  Dividend;
285     UINT8                   ValidDigits = 0;
286     UINT8                   SignOf0x = 0;
287     UINT8                   Term = 0;
288 
289 
290     ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
291 
292 
293     switch (Base)
294     {
295     case ACPI_ANY_BASE:
296     case 10:
297     case 16:
298 
299         break;
300 
301     default:
302 
303         /* Invalid Base */
304 
305         return_ACPI_STATUS (AE_BAD_PARAMETER);
306     }
307 
308     if (!String)
309     {
310         goto ErrorExit;
311     }
312 
313     /* Skip over any white space in the buffer */
314 
315     while ((*String) && (isspace ((int) *String) || *String == '\t'))
316     {
317         String++;
318     }
319 
320     if (Base == ACPI_ANY_BASE)
321     {
322         /*
323          * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'.
324          * We need to determine if it is decimal or hexadecimal.
325          */
326         if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
327         {
328             SignOf0x = 1;
329             Base = 16;
330 
331             /* Skip over the leading '0x' */
332             String += 2;
333         }
334         else
335         {
336             Base = 10;
337         }
338     }
339 
340     /* Any string left? Check that '0x' is not followed by white space. */
341 
342     if (!(*String) || isspace ((int) *String) || *String == '\t')
343     {
344         if (Base == ACPI_ANY_BASE)
345         {
346             goto ErrorExit;
347         }
348         else
349         {
350             goto AllDone;
351         }
352     }
353 
354     /*
355      * Perform a 32-bit or 64-bit conversion, depending upon the input
356      * byte width
357      */
358     Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ?
359         ACPI_UINT32_MAX : ACPI_UINT64_MAX;
360 
361     /* Main loop: convert the string to a 32- or 64-bit integer */
362 
363     while (*String)
364     {
365         if (isdigit ((int) *String))
366         {
367             /* Convert ASCII 0-9 to Decimal value */
368 
369             ThisDigit = ((UINT8) *String) - '0';
370         }
371         else if (Base == 10)
372         {
373             /* Digit is out of range; possible in ToInteger case only */
374 
375             Term = 1;
376         }
377         else
378         {
379             ThisDigit = (UINT8) toupper ((int) *String);
380             if (isxdigit ((int) ThisDigit))
381             {
382                 /* Convert ASCII Hex char to value */
383 
384                 ThisDigit = ThisDigit - 'A' + 10;
385             }
386             else
387             {
388                 Term = 1;
389             }
390         }
391 
392         if (Term)
393         {
394             if (Base == ACPI_ANY_BASE)
395             {
396                 goto ErrorExit;
397             }
398             else
399             {
400                 break;
401             }
402         }
403         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
404         {
405             /* Skip zeros */
406             String++;
407             continue;
408         }
409 
410         ValidDigits++;
411 
412         if (SignOf0x && ((ValidDigits > 16) ||
413             ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH))))
414         {
415             /*
416              * This is ToInteger operation case.
417              * No restrictions for string-to-integer conversion,
418              * see ACPI spec.
419              */
420             goto ErrorExit;
421         }
422 
423         /* Divide the digit into the correct position */
424 
425         (void) AcpiUtShortDivide (
426             (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL);
427 
428         if (ReturnValue > Quotient)
429         {
430             if (Base == ACPI_ANY_BASE)
431             {
432                 goto ErrorExit;
433             }
434             else
435             {
436                 break;
437             }
438         }
439 
440         ReturnValue *= Base;
441         ReturnValue += ThisDigit;
442         String++;
443     }
444 
445     /* All done, normal exit */
446 
447 AllDone:
448 
449     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
450         ACPI_FORMAT_UINT64 (ReturnValue)));
451 
452     *RetInteger = ReturnValue;
453     return_ACPI_STATUS (AE_OK);
454 
455 
456 ErrorExit:
457 
458     /* Base was set/validated above (10 or 16) */
459 
460     if (Base == 10)
461     {
462         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
463     }
464     else
465     {
466         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
467     }
468 }
469 
470 
471 #ifdef _OBSOLETE_FUNCTIONS
472 /* Removed: 01/2016 */
473 
474 /*******************************************************************************
475  *
476  * FUNCTION:    strtoul64
477  *
478  * PARAMETERS:  String              - Null terminated string
479  *              Terminater          - Where a pointer to the terminating byte
480  *                                    is returned
481  *              Base                - Radix of the string
482  *
483  * RETURN:      Converted value
484  *
485  * DESCRIPTION: Convert a string into an unsigned value.
486  *
487  ******************************************************************************/
488 
489 ACPI_STATUS
strtoul64(char * String,UINT32 Base,UINT64 * RetInteger)490 strtoul64 (
491     char                    *String,
492     UINT32                  Base,
493     UINT64                  *RetInteger)
494 {
495     UINT32                  Index;
496     UINT32                  Sign;
497     UINT64                  ReturnValue = 0;
498     ACPI_STATUS             Status = AE_OK;
499 
500 
501     *RetInteger = 0;
502 
503     switch (Base)
504     {
505     case 0:
506     case 8:
507     case 10:
508     case 16:
509 
510         break;
511 
512     default:
513         /*
514          * The specified Base parameter is not in the domain of
515          * this function:
516          */
517         return (AE_BAD_PARAMETER);
518     }
519 
520     /* Skip over any white space in the buffer: */
521 
522     while (isspace ((int) *String) || *String == '\t')
523     {
524         ++String;
525     }
526 
527     /*
528      * The buffer may contain an optional plus or minus sign.
529      * If it does, then skip over it but remember what is was:
530      */
531     if (*String == '-')
532     {
533         Sign = ACPI_SIGN_NEGATIVE;
534         ++String;
535     }
536     else if (*String == '+')
537     {
538         ++String;
539         Sign = ACPI_SIGN_POSITIVE;
540     }
541     else
542     {
543         Sign = ACPI_SIGN_POSITIVE;
544     }
545 
546     /*
547      * If the input parameter Base is zero, then we need to
548      * determine if it is octal, decimal, or hexadecimal:
549      */
550     if (Base == 0)
551     {
552         if (*String == '0')
553         {
554             if (tolower ((int) *(++String)) == 'x')
555             {
556                 Base = 16;
557                 ++String;
558             }
559             else
560             {
561                 Base = 8;
562             }
563         }
564         else
565         {
566             Base = 10;
567         }
568     }
569 
570     /*
571      * For octal and hexadecimal bases, skip over the leading
572      * 0 or 0x, if they are present.
573      */
574     if (Base == 8 && *String == '0')
575     {
576         String++;
577     }
578 
579     if (Base == 16 &&
580         *String == '0' &&
581         tolower ((int) *(++String)) == 'x')
582     {
583         String++;
584     }
585 
586     /* Main loop: convert the string to an unsigned long */
587 
588     while (*String)
589     {
590         if (isdigit ((int) *String))
591         {
592             Index = ((UINT8) *String) - '0';
593         }
594         else
595         {
596             Index = (UINT8) toupper ((int) *String);
597             if (isupper ((int) Index))
598             {
599                 Index = Index - 'A' + 10;
600             }
601             else
602             {
603                 goto ErrorExit;
604             }
605         }
606 
607         if (Index >= Base)
608         {
609             goto ErrorExit;
610         }
611 
612         /* Check to see if value is out of range: */
613 
614         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
615             (UINT64) Base))
616         {
617             goto ErrorExit;
618         }
619         else
620         {
621             ReturnValue *= Base;
622             ReturnValue += Index;
623         }
624 
625         ++String;
626     }
627 
628 
629     /* If a minus sign was present, then "the conversion is negated": */
630 
631     if (Sign == ACPI_SIGN_NEGATIVE)
632     {
633         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
634     }
635 
636     *RetInteger = ReturnValue;
637     return (Status);
638 
639 
640 ErrorExit:
641     switch (Base)
642     {
643     case 8:
644 
645         Status = AE_BAD_OCTAL_CONSTANT;
646         break;
647 
648     case 10:
649 
650         Status = AE_BAD_DECIMAL_CONSTANT;
651         break;
652 
653     case 16:
654 
655         Status = AE_BAD_HEX_CONSTANT;
656         break;
657 
658     default:
659 
660         /* Base validated above */
661 
662         break;
663     }
664 
665     return (Status);
666 }
667 #endif
668