]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/dev/acpica/components/utilities/utstring.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / dev / acpica / components / utilities / utstring.c
1 /*******************************************************************************
2  *
3  * Module Name: utstring - Common functions for strings and characters
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2013, 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
45 #define __UTSTRING_C__
46
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50
51
52 #define _COMPONENT          ACPI_UTILITIES
53         ACPI_MODULE_NAME    ("utstring")
54
55
56 /*
57  * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
58  * version of strtoul.
59  */
60
61 #ifdef ACPI_ASL_COMPILER
62 /*******************************************************************************
63  *
64  * FUNCTION:    AcpiUtStrlwr (strlwr)
65  *
66  * PARAMETERS:  SrcString       - The source string to convert
67  *
68  * RETURN:      None
69  *
70  * DESCRIPTION: Convert string to lowercase
71  *
72  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
73  *
74  ******************************************************************************/
75
76 void
77 AcpiUtStrlwr (
78     char                    *SrcString)
79 {
80     char                    *String;
81
82
83     ACPI_FUNCTION_ENTRY ();
84
85
86     if (!SrcString)
87     {
88         return;
89     }
90
91     /* Walk entire string, lowercasing the letters */
92
93     for (String = SrcString; *String; String++)
94     {
95         *String = (char) ACPI_TOLOWER (*String);
96     }
97
98     return;
99 }
100
101
102 /******************************************************************************
103  *
104  * FUNCTION:    AcpiUtStricmp (stricmp)
105  *
106  * PARAMETERS:  String1             - first string to compare
107  *              String2             - second string to compare
108  *
109  * RETURN:      int that signifies string relationship. Zero means strings
110  *              are equal.
111  *
112  * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
113  *              strings with no case sensitivity)
114  *
115  ******************************************************************************/
116
117 int
118 AcpiUtStricmp (
119     char                    *String1,
120     char                    *String2)
121 {
122     int                     c1;
123     int                     c2;
124
125
126     do
127     {
128         c1 = tolower ((int) *String1);
129         c2 = tolower ((int) *String2);
130
131         String1++;
132         String2++;
133     }
134     while ((c1 == c2) && (c1));
135
136     return (c1 - c2);
137 }
138 #endif
139
140
141 /*******************************************************************************
142  *
143  * FUNCTION:    AcpiUtStrupr (strupr)
144  *
145  * PARAMETERS:  SrcString       - The source string to convert
146  *
147  * RETURN:      None
148  *
149  * DESCRIPTION: Convert string to uppercase
150  *
151  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
152  *
153  ******************************************************************************/
154
155 void
156 AcpiUtStrupr (
157     char                    *SrcString)
158 {
159     char                    *String;
160
161
162     ACPI_FUNCTION_ENTRY ();
163
164
165     if (!SrcString)
166     {
167         return;
168     }
169
170     /* Walk entire string, uppercasing the letters */
171
172     for (String = SrcString; *String; String++)
173     {
174         *String = (char) ACPI_TOUPPER (*String);
175     }
176
177     return;
178 }
179
180
181 /*******************************************************************************
182  *
183  * FUNCTION:    AcpiUtStrtoul64
184  *
185  * PARAMETERS:  String          - Null terminated string
186  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
187  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
188  *              RetInteger      - Where the converted integer is returned
189  *
190  * RETURN:      Status and Converted value
191  *
192  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
193  *              32-bit or 64-bit conversion, depending on the current mode
194  *              of the interpreter.
195  *              NOTE: Does not support Octal strings, not needed.
196  *
197  ******************************************************************************/
198
199 ACPI_STATUS
200 AcpiUtStrtoul64 (
201     char                    *String,
202     UINT32                  Base,
203     UINT64                  *RetInteger)
204 {
205     UINT32                  ThisDigit = 0;
206     UINT64                  ReturnValue = 0;
207     UINT64                  Quotient;
208     UINT64                  Dividend;
209     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
210     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
211     UINT8                   ValidDigits = 0;
212     UINT8                   SignOf0x = 0;
213     UINT8                   Term = 0;
214
215
216     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
217
218
219     switch (Base)
220     {
221     case ACPI_ANY_BASE:
222     case 16:
223
224         break;
225
226     default:
227
228         /* Invalid Base */
229
230         return_ACPI_STATUS (AE_BAD_PARAMETER);
231     }
232
233     if (!String)
234     {
235         goto ErrorExit;
236     }
237
238     /* Skip over any white space in the buffer */
239
240     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
241     {
242         String++;
243     }
244
245     if (ToIntegerOp)
246     {
247         /*
248          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
249          * We need to determine if it is decimal or hexadecimal.
250          */
251         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
252         {
253             SignOf0x = 1;
254             Base = 16;
255
256             /* Skip over the leading '0x' */
257             String += 2;
258         }
259         else
260         {
261             Base = 10;
262         }
263     }
264
265     /* Any string left? Check that '0x' is not followed by white space. */
266
267     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
268     {
269         if (ToIntegerOp)
270         {
271             goto ErrorExit;
272         }
273         else
274         {
275             goto AllDone;
276         }
277     }
278
279     /*
280      * Perform a 32-bit or 64-bit conversion, depending upon the current
281      * execution mode of the interpreter
282      */
283     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
284
285     /* Main loop: convert the string to a 32- or 64-bit integer */
286
287     while (*String)
288     {
289         if (ACPI_IS_DIGIT (*String))
290         {
291             /* Convert ASCII 0-9 to Decimal value */
292
293             ThisDigit = ((UINT8) *String) - '0';
294         }
295         else if (Base == 10)
296         {
297             /* Digit is out of range; possible in ToInteger case only */
298
299             Term = 1;
300         }
301         else
302         {
303             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
304             if (ACPI_IS_XDIGIT ((char) ThisDigit))
305             {
306                 /* Convert ASCII Hex char to value */
307
308                 ThisDigit = ThisDigit - 'A' + 10;
309             }
310             else
311             {
312                 Term = 1;
313             }
314         }
315
316         if (Term)
317         {
318             if (ToIntegerOp)
319             {
320                 goto ErrorExit;
321             }
322             else
323             {
324                 break;
325             }
326         }
327         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
328         {
329             /* Skip zeros */
330             String++;
331             continue;
332         }
333
334         ValidDigits++;
335
336         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
337         {
338             /*
339              * This is ToInteger operation case.
340              * No any restrictions for string-to-integer conversion,
341              * see ACPI spec.
342              */
343             goto ErrorExit;
344         }
345
346         /* Divide the digit into the correct position */
347
348         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
349                     Base, &Quotient, NULL);
350
351         if (ReturnValue > Quotient)
352         {
353             if (ToIntegerOp)
354             {
355                 goto ErrorExit;
356             }
357             else
358             {
359                 break;
360             }
361         }
362
363         ReturnValue *= Base;
364         ReturnValue += ThisDigit;
365         String++;
366     }
367
368     /* All done, normal exit */
369
370 AllDone:
371
372     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
373         ACPI_FORMAT_UINT64 (ReturnValue)));
374
375     *RetInteger = ReturnValue;
376     return_ACPI_STATUS (AE_OK);
377
378
379 ErrorExit:
380     /* Base was set/validated above */
381
382     if (Base == 10)
383     {
384         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
385     }
386     else
387     {
388         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
389     }
390 }
391
392
393 /*******************************************************************************
394  *
395  * FUNCTION:    AcpiUtPrintString
396  *
397  * PARAMETERS:  String          - Null terminated ASCII string
398  *              MaxLength       - Maximum output length. Used to constrain the
399  *                                length of strings during debug output only.
400  *
401  * RETURN:      None
402  *
403  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
404  *              sequences.
405  *
406  ******************************************************************************/
407
408 void
409 AcpiUtPrintString (
410     char                    *String,
411     UINT16                  MaxLength)
412 {
413     UINT32                  i;
414
415
416     if (!String)
417     {
418         AcpiOsPrintf ("<\"NULL STRING PTR\">");
419         return;
420     }
421
422     AcpiOsPrintf ("\"");
423     for (i = 0; String[i] && (i < MaxLength); i++)
424     {
425         /* Escape sequences */
426
427         switch (String[i])
428         {
429         case 0x07:
430
431             AcpiOsPrintf ("\\a");       /* BELL */
432             break;
433
434         case 0x08:
435
436             AcpiOsPrintf ("\\b");       /* BACKSPACE */
437             break;
438
439         case 0x0C:
440
441             AcpiOsPrintf ("\\f");       /* FORMFEED */
442             break;
443
444         case 0x0A:
445
446             AcpiOsPrintf ("\\n");       /* LINEFEED */
447             break;
448
449         case 0x0D:
450
451             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
452             break;
453
454         case 0x09:
455
456             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
457             break;
458
459         case 0x0B:
460
461             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
462             break;
463
464         case '\'':                      /* Single Quote */
465         case '\"':                      /* Double Quote */
466         case '\\':                      /* Backslash */
467
468             AcpiOsPrintf ("\\%c", (int) String[i]);
469             break;
470
471         default:
472
473             /* Check for printable character or hex escape */
474
475             if (ACPI_IS_PRINT (String[i]))
476             {
477                 /* This is a normal character */
478
479                 AcpiOsPrintf ("%c", (int) String[i]);
480             }
481             else
482             {
483                 /* All others will be Hex escapes */
484
485                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
486             }
487             break;
488         }
489     }
490     AcpiOsPrintf ("\"");
491
492     if (i == MaxLength && String[i])
493     {
494         AcpiOsPrintf ("...");
495     }
496 }
497
498
499 /*******************************************************************************
500  *
501  * FUNCTION:    AcpiUtValidAcpiChar
502  *
503  * PARAMETERS:  Char            - The character to be examined
504  *              Position        - Byte position (0-3)
505  *
506  * RETURN:      TRUE if the character is valid, FALSE otherwise
507  *
508  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
509  *              1) Upper case alpha
510  *              2) numeric
511  *              3) underscore
512  *
513  *              We allow a '!' as the last character because of the ASF! table
514  *
515  ******************************************************************************/
516
517 BOOLEAN
518 AcpiUtValidAcpiChar (
519     char                    Character,
520     UINT32                  Position)
521 {
522
523     if (!((Character >= 'A' && Character <= 'Z') ||
524           (Character >= '0' && Character <= '9') ||
525           (Character == '_')))
526     {
527         /* Allow a '!' in the last position */
528
529         if (Character == '!' && Position == 3)
530         {
531             return (TRUE);
532         }
533
534         return (FALSE);
535     }
536
537     return (TRUE);
538 }
539
540
541 /*******************************************************************************
542  *
543  * FUNCTION:    AcpiUtValidAcpiName
544  *
545  * PARAMETERS:  Name            - The name to be examined. Does not have to
546  *                                be NULL terminated string.
547  *
548  * RETURN:      TRUE if the name is valid, FALSE otherwise
549  *
550  * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
551  *              1) Upper case alpha
552  *              2) numeric
553  *              3) underscore
554  *
555  ******************************************************************************/
556
557 BOOLEAN
558 AcpiUtValidAcpiName (
559     char                    *Name)
560 {
561     UINT32                  i;
562
563
564     ACPI_FUNCTION_ENTRY ();
565
566
567     for (i = 0; i < ACPI_NAME_SIZE; i++)
568     {
569         if (!AcpiUtValidAcpiChar (Name[i], i))
570         {
571             return (FALSE);
572         }
573     }
574
575     return (TRUE);
576 }
577
578
579 /*******************************************************************************
580  *
581  * FUNCTION:    AcpiUtRepairName
582  *
583  * PARAMETERS:  Name            - The ACPI name to be repaired
584  *
585  * RETURN:      Repaired version of the name
586  *
587  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
588  *              return the new name. NOTE: the Name parameter must reside in
589  *              read/write memory, cannot be a const.
590  *
591  * An ACPI Name must consist of valid ACPI characters. We will repair the name
592  * if necessary because we don't want to abort because of this, but we want
593  * all namespace names to be printable. A warning message is appropriate.
594  *
595  * This issue came up because there are in fact machines that exhibit
596  * this problem, and we want to be able to enable ACPI support for them,
597  * even though there are a few bad names.
598  *
599  ******************************************************************************/
600
601 void
602 AcpiUtRepairName (
603     char                    *Name)
604 {
605     UINT32                  i;
606     BOOLEAN                 FoundBadChar = FALSE;
607     UINT32                  OriginalName;
608
609
610     ACPI_FUNCTION_NAME (UtRepairName);
611
612
613     ACPI_MOVE_NAME (&OriginalName, Name);
614
615     /* Check each character in the name */
616
617     for (i = 0; i < ACPI_NAME_SIZE; i++)
618     {
619         if (AcpiUtValidAcpiChar (Name[i], i))
620         {
621             continue;
622         }
623
624         /*
625          * Replace a bad character with something printable, yet technically
626          * still invalid. This prevents any collisions with existing "good"
627          * names in the namespace.
628          */
629         Name[i] = '*';
630         FoundBadChar = TRUE;
631     }
632
633     if (FoundBadChar)
634     {
635         /* Report warning only if in strict mode or debug mode */
636
637         if (!AcpiGbl_EnableInterpreterSlack)
638         {
639             ACPI_WARNING ((AE_INFO,
640                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
641                 OriginalName, Name));
642         }
643         else
644         {
645             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
646                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
647                 OriginalName, Name));
648         }
649     }
650 }
651
652
653 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
654 /*******************************************************************************
655  *
656  * FUNCTION:    UtConvertBackslashes
657  *
658  * PARAMETERS:  Pathname        - File pathname string to be converted
659  *
660  * RETURN:      Modifies the input Pathname
661  *
662  * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
663  *              the entire input file pathname string.
664  *
665  ******************************************************************************/
666
667 void
668 UtConvertBackslashes (
669     char                    *Pathname)
670 {
671
672     if (!Pathname)
673     {
674         return;
675     }
676
677     while (*Pathname)
678     {
679         if (*Pathname == '\\')
680         {
681             *Pathname = '/';
682         }
683
684         Pathname++;
685     }
686 }
687 #endif