xref: /freebsd/sys/contrib/dev/acpica/components/utilities/utnonansi.c (revision 4436b51dff5736e74da464946049ea6899a88938)
1 /*******************************************************************************
2  *
3  * Module Name: utnonansi - Non-ansi C library functions
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/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
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
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
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 /*******************************************************************************
168  *
169  * FUNCTION:    AcpiUtStrtoul64
170  *
171  * PARAMETERS:  String          - Null terminated string
172  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
173  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
174  *              RetInteger      - Where the converted integer is returned
175  *
176  * RETURN:      Status and Converted value
177  *
178  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
179  *              32-bit or 64-bit conversion, depending on the current mode
180  *              of the interpreter.
181  *
182  * NOTE:        Does not support Octal strings, not needed.
183  *
184  ******************************************************************************/
185 
186 ACPI_STATUS
187 AcpiUtStrtoul64 (
188     char                    *String,
189     UINT32                  Base,
190     UINT64                  *RetInteger)
191 {
192     UINT32                  ThisDigit = 0;
193     UINT64                  ReturnValue = 0;
194     UINT64                  Quotient;
195     UINT64                  Dividend;
196     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
197     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
198     UINT8                   ValidDigits = 0;
199     UINT8                   SignOf0x = 0;
200     UINT8                   Term = 0;
201 
202 
203     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
204 
205 
206     switch (Base)
207     {
208     case ACPI_ANY_BASE:
209     case 16:
210 
211         break;
212 
213     default:
214 
215         /* Invalid Base */
216 
217         return_ACPI_STATUS (AE_BAD_PARAMETER);
218     }
219 
220     if (!String)
221     {
222         goto ErrorExit;
223     }
224 
225     /* Skip over any white space in the buffer */
226 
227     while ((*String) && (isspace ((int) *String) || *String == '\t'))
228     {
229         String++;
230     }
231 
232     if (ToIntegerOp)
233     {
234         /*
235          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
236          * We need to determine if it is decimal or hexadecimal.
237          */
238         if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
239         {
240             SignOf0x = 1;
241             Base = 16;
242 
243             /* Skip over the leading '0x' */
244             String += 2;
245         }
246         else
247         {
248             Base = 10;
249         }
250     }
251 
252     /* Any string left? Check that '0x' is not followed by white space. */
253 
254     if (!(*String) || isspace ((int) *String) || *String == '\t')
255     {
256         if (ToIntegerOp)
257         {
258             goto ErrorExit;
259         }
260         else
261         {
262             goto AllDone;
263         }
264     }
265 
266     /*
267      * Perform a 32-bit or 64-bit conversion, depending upon the current
268      * execution mode of the interpreter
269      */
270     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
271 
272     /* Main loop: convert the string to a 32- or 64-bit integer */
273 
274     while (*String)
275     {
276         if (isdigit ((int) *String))
277         {
278             /* Convert ASCII 0-9 to Decimal value */
279 
280             ThisDigit = ((UINT8) *String) - '0';
281         }
282         else if (Base == 10)
283         {
284             /* Digit is out of range; possible in ToInteger case only */
285 
286             Term = 1;
287         }
288         else
289         {
290             ThisDigit = (UINT8) toupper ((int) *String);
291             if (isxdigit ((int) ThisDigit))
292             {
293                 /* Convert ASCII Hex char to value */
294 
295                 ThisDigit = ThisDigit - 'A' + 10;
296             }
297             else
298             {
299                 Term = 1;
300             }
301         }
302 
303         if (Term)
304         {
305             if (ToIntegerOp)
306             {
307                 goto ErrorExit;
308             }
309             else
310             {
311                 break;
312             }
313         }
314         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
315         {
316             /* Skip zeros */
317             String++;
318             continue;
319         }
320 
321         ValidDigits++;
322 
323         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
324         {
325             /*
326              * This is ToInteger operation case.
327              * No any restrictions for string-to-integer conversion,
328              * see ACPI spec.
329              */
330             goto ErrorExit;
331         }
332 
333         /* Divide the digit into the correct position */
334 
335         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
336                     Base, &Quotient, NULL);
337 
338         if (ReturnValue > Quotient)
339         {
340             if (ToIntegerOp)
341             {
342                 goto ErrorExit;
343             }
344             else
345             {
346                 break;
347             }
348         }
349 
350         ReturnValue *= Base;
351         ReturnValue += ThisDigit;
352         String++;
353     }
354 
355     /* All done, normal exit */
356 
357 AllDone:
358 
359     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
360         ACPI_FORMAT_UINT64 (ReturnValue)));
361 
362     *RetInteger = ReturnValue;
363     return_ACPI_STATUS (AE_OK);
364 
365 
366 ErrorExit:
367     /* Base was set/validated above */
368 
369     if (Base == 10)
370     {
371         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
372     }
373     else
374     {
375         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
376     }
377 }
378 
379 
380 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
381 /*******************************************************************************
382  *
383  * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat
384  *
385  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
386  *              functions. This is the size of the Destination buffer.
387  *
388  * RETURN:      TRUE if the operation would overflow the destination buffer.
389  *
390  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
391  *              the result of the operation will not overflow the output string
392  *              buffer.
393  *
394  * NOTE:        These functions are typically only helpful for processing
395  *              user input and command lines. For most ACPICA code, the
396  *              required buffer length is precisely calculated before buffer
397  *              allocation, so the use of these functions is unnecessary.
398  *
399  ******************************************************************************/
400 
401 BOOLEAN
402 AcpiUtSafeStrcpy (
403     char                    *Dest,
404     ACPI_SIZE               DestSize,
405     char                    *Source)
406 {
407 
408     if (strlen (Source) >= DestSize)
409     {
410         return (TRUE);
411     }
412 
413     strcpy (Dest, Source);
414     return (FALSE);
415 }
416 
417 BOOLEAN
418 AcpiUtSafeStrcat (
419     char                    *Dest,
420     ACPI_SIZE               DestSize,
421     char                    *Source)
422 {
423 
424     if ((strlen (Dest) + strlen (Source)) >= DestSize)
425     {
426         return (TRUE);
427     }
428 
429     strcat (Dest, Source);
430     return (FALSE);
431 }
432 #endif
433