]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/components/utilities/utstring.c
Merge ACPICA 20130117.
[FreeBSD/FreeBSD.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         break;
224
225     default:
226         /* Invalid Base */
227         return_ACPI_STATUS (AE_BAD_PARAMETER);
228     }
229
230     if (!String)
231     {
232         goto ErrorExit;
233     }
234
235     /* Skip over any white space in the buffer */
236
237     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
238     {
239         String++;
240     }
241
242     if (ToIntegerOp)
243     {
244         /*
245          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
246          * We need to determine if it is decimal or hexadecimal.
247          */
248         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
249         {
250             SignOf0x = 1;
251             Base = 16;
252
253             /* Skip over the leading '0x' */
254             String += 2;
255         }
256         else
257         {
258             Base = 10;
259         }
260     }
261
262     /* Any string left? Check that '0x' is not followed by white space. */
263
264     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
265     {
266         if (ToIntegerOp)
267         {
268             goto ErrorExit;
269         }
270         else
271         {
272             goto AllDone;
273         }
274     }
275
276     /*
277      * Perform a 32-bit or 64-bit conversion, depending upon the current
278      * execution mode of the interpreter
279      */
280     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
281
282     /* Main loop: convert the string to a 32- or 64-bit integer */
283
284     while (*String)
285     {
286         if (ACPI_IS_DIGIT (*String))
287         {
288             /* Convert ASCII 0-9 to Decimal value */
289
290             ThisDigit = ((UINT8) *String) - '0';
291         }
292         else if (Base == 10)
293         {
294             /* Digit is out of range; possible in ToInteger case only */
295
296             Term = 1;
297         }
298         else
299         {
300             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
301             if (ACPI_IS_XDIGIT ((char) ThisDigit))
302             {
303                 /* Convert ASCII Hex char to value */
304
305                 ThisDigit = ThisDigit - 'A' + 10;
306             }
307             else
308             {
309                 Term = 1;
310             }
311         }
312
313         if (Term)
314         {
315             if (ToIntegerOp)
316             {
317                 goto ErrorExit;
318             }
319             else
320             {
321                 break;
322             }
323         }
324         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
325         {
326             /* Skip zeros */
327             String++;
328             continue;
329         }
330
331         ValidDigits++;
332
333         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
334         {
335             /*
336              * This is ToInteger operation case.
337              * No any restrictions for string-to-integer conversion,
338              * see ACPI spec.
339              */
340             goto ErrorExit;
341         }
342
343         /* Divide the digit into the correct position */
344
345         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
346                     Base, &Quotient, NULL);
347
348         if (ReturnValue > Quotient)
349         {
350             if (ToIntegerOp)
351             {
352                 goto ErrorExit;
353             }
354             else
355             {
356                 break;
357             }
358         }
359
360         ReturnValue *= Base;
361         ReturnValue += ThisDigit;
362         String++;
363     }
364
365     /* All done, normal exit */
366
367 AllDone:
368
369     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
370         ACPI_FORMAT_UINT64 (ReturnValue)));
371
372     *RetInteger = ReturnValue;
373     return_ACPI_STATUS (AE_OK);
374
375
376 ErrorExit:
377     /* Base was set/validated above */
378
379     if (Base == 10)
380     {
381         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
382     }
383     else
384     {
385         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
386     }
387 }
388
389
390 /*******************************************************************************
391  *
392  * FUNCTION:    AcpiUtPrintString
393  *
394  * PARAMETERS:  String          - Null terminated ASCII string
395  *              MaxLength       - Maximum output length
396  *
397  * RETURN:      None
398  *
399  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
400  *              sequences.
401  *
402  ******************************************************************************/
403
404 void
405 AcpiUtPrintString (
406     char                    *String,
407     UINT8                   MaxLength)
408 {
409     UINT32                  i;
410
411
412     if (!String)
413     {
414         AcpiOsPrintf ("<\"NULL STRING PTR\">");
415         return;
416     }
417
418     AcpiOsPrintf ("\"");
419     for (i = 0; String[i] && (i < MaxLength); i++)
420     {
421         /* Escape sequences */
422
423         switch (String[i])
424         {
425         case 0x07:
426             AcpiOsPrintf ("\\a");       /* BELL */
427             break;
428
429         case 0x08:
430             AcpiOsPrintf ("\\b");       /* BACKSPACE */
431             break;
432
433         case 0x0C:
434             AcpiOsPrintf ("\\f");       /* FORMFEED */
435             break;
436
437         case 0x0A:
438             AcpiOsPrintf ("\\n");       /* LINEFEED */
439             break;
440
441         case 0x0D:
442             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
443             break;
444
445         case 0x09:
446             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
447             break;
448
449         case 0x0B:
450             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
451             break;
452
453         case '\'':                      /* Single Quote */
454         case '\"':                      /* Double Quote */
455         case '\\':                      /* Backslash */
456             AcpiOsPrintf ("\\%c", (int) String[i]);
457             break;
458
459         default:
460
461             /* Check for printable character or hex escape */
462
463             if (ACPI_IS_PRINT (String[i]))
464             {
465                 /* This is a normal character */
466
467                 AcpiOsPrintf ("%c", (int) String[i]);
468             }
469             else
470             {
471                 /* All others will be Hex escapes */
472
473                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
474             }
475             break;
476         }
477     }
478     AcpiOsPrintf ("\"");
479
480     if (i == MaxLength && String[i])
481     {
482         AcpiOsPrintf ("...");
483     }
484 }
485
486
487 /*******************************************************************************
488  *
489  * FUNCTION:    AcpiUtValidAcpiChar
490  *
491  * PARAMETERS:  Char            - The character to be examined
492  *              Position        - Byte position (0-3)
493  *
494  * RETURN:      TRUE if the character is valid, FALSE otherwise
495  *
496  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
497  *              1) Upper case alpha
498  *              2) numeric
499  *              3) underscore
500  *
501  *              We allow a '!' as the last character because of the ASF! table
502  *
503  ******************************************************************************/
504
505 BOOLEAN
506 AcpiUtValidAcpiChar (
507     char                    Character,
508     UINT32                  Position)
509 {
510
511     if (!((Character >= 'A' && Character <= 'Z') ||
512           (Character >= '0' && Character <= '9') ||
513           (Character == '_')))
514     {
515         /* Allow a '!' in the last position */
516
517         if (Character == '!' && Position == 3)
518         {
519             return (TRUE);
520         }
521
522         return (FALSE);
523     }
524
525     return (TRUE);
526 }
527
528
529 /*******************************************************************************
530  *
531  * FUNCTION:    AcpiUtValidAcpiName
532  *
533  * PARAMETERS:  Name            - The name to be examined
534  *
535  * RETURN:      TRUE if the name is valid, FALSE otherwise
536  *
537  * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
538  *              1) Upper case alpha
539  *              2) numeric
540  *              3) underscore
541  *
542  ******************************************************************************/
543
544 BOOLEAN
545 AcpiUtValidAcpiName (
546     UINT32                  Name)
547 {
548     UINT32                  i;
549
550
551     ACPI_FUNCTION_ENTRY ();
552
553
554     for (i = 0; i < ACPI_NAME_SIZE; i++)
555     {
556         if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
557         {
558             return (FALSE);
559         }
560     }
561
562     return (TRUE);
563 }
564
565
566 /*******************************************************************************
567  *
568  * FUNCTION:    AcpiUtRepairName
569  *
570  * PARAMETERS:  Name            - The ACPI name to be repaired
571  *
572  * RETURN:      Repaired version of the name
573  *
574  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
575  *              return the new name. NOTE: the Name parameter must reside in
576  *              read/write memory, cannot be a const.
577  *
578  * An ACPI Name must consist of valid ACPI characters. We will repair the name
579  * if necessary because we don't want to abort because of this, but we want
580  * all namespace names to be printable. A warning message is appropriate.
581  *
582  * This issue came up because there are in fact machines that exhibit
583  * this problem, and we want to be able to enable ACPI support for them,
584  * even though there are a few bad names.
585  *
586  ******************************************************************************/
587
588 void
589 AcpiUtRepairName (
590     char                    *Name)
591 {
592     UINT32                  i;
593     BOOLEAN                 FoundBadChar = FALSE;
594     UINT32                  OriginalName;
595
596
597     ACPI_FUNCTION_NAME (UtRepairName);
598
599
600     ACPI_MOVE_NAME (&OriginalName, Name);
601
602     /* Check each character in the name */
603
604     for (i = 0; i < ACPI_NAME_SIZE; i++)
605     {
606         if (AcpiUtValidAcpiChar (Name[i], i))
607         {
608             continue;
609         }
610
611         /*
612          * Replace a bad character with something printable, yet technically
613          * still invalid. This prevents any collisions with existing "good"
614          * names in the namespace.
615          */
616         Name[i] = '*';
617         FoundBadChar = TRUE;
618     }
619
620     if (FoundBadChar)
621     {
622         /* Report warning only if in strict mode or debug mode */
623
624         if (!AcpiGbl_EnableInterpreterSlack)
625         {
626             ACPI_WARNING ((AE_INFO,
627                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
628                 OriginalName, Name));
629         }
630         else
631         {
632             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
633                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
634                 OriginalName, Name));
635         }
636     }
637 }
638
639
640 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
641 /*******************************************************************************
642  *
643  * FUNCTION:    UtConvertBackslashes
644  *
645  * PARAMETERS:  Pathname        - File pathname string to be converted
646  *
647  * RETURN:      Modifies the input Pathname
648  *
649  * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
650  *              the entire input file pathname string.
651  *
652  ******************************************************************************/
653
654 void
655 UtConvertBackslashes (
656     char                    *Pathname)
657 {
658
659     if (!Pathname)
660     {
661         return;
662     }
663
664     while (*Pathname)
665     {
666         if (*Pathname == '\\')
667         {
668             *Pathname = '/';
669         }
670
671         Pathname++;
672     }
673 }
674 #endif