[ACPI]
[reactos.git] / reactos / drivers / bus / acpi / acpica / utilities / utstring.c
1 /*******************************************************************************
2 *
3 * Module Name: utstring - Common functions for strings and characters
4 *
5 ******************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2014, 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
117 #define __UTSTRING_C__
118
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acnamesp.h"
122
123
124 #define _COMPONENT ACPI_UTILITIES
125 ACPI_MODULE_NAME ("utstring")
126
127
128 /*
129 * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
130 * version of strtoul.
131 */
132
133 #ifdef ACPI_ASL_COMPILER
134 /*******************************************************************************
135 *
136 * FUNCTION: AcpiUtStrlwr (strlwr)
137 *
138 * PARAMETERS: SrcString - The source string to convert
139 *
140 * RETURN: None
141 *
142 * DESCRIPTION: Convert string to lowercase
143 *
144 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
145 *
146 ******************************************************************************/
147
148 void
149 AcpiUtStrlwr (
150 char *SrcString)
151 {
152 char *String;
153
154
155 ACPI_FUNCTION_ENTRY ();
156
157
158 if (!SrcString)
159 {
160 return;
161 }
162
163 /* Walk entire string, lowercasing the letters */
164
165 for (String = SrcString; *String; String++)
166 {
167 *String = (char) ACPI_TOLOWER (*String);
168 }
169
170 return;
171 }
172
173
174 /******************************************************************************
175 *
176 * FUNCTION: AcpiUtStricmp (stricmp)
177 *
178 * PARAMETERS: String1 - first string to compare
179 * String2 - second string to compare
180 *
181 * RETURN: int that signifies string relationship. Zero means strings
182 * are equal.
183 *
184 * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
185 * strings with no case sensitivity)
186 *
187 ******************************************************************************/
188
189 int
190 AcpiUtStricmp (
191 char *String1,
192 char *String2)
193 {
194 int c1;
195 int c2;
196
197
198 do
199 {
200 c1 = tolower ((int) *String1);
201 c2 = tolower ((int) *String2);
202
203 String1++;
204 String2++;
205 }
206 while ((c1 == c2) && (c1));
207
208 return (c1 - c2);
209 }
210 #endif
211
212
213 /*******************************************************************************
214 *
215 * FUNCTION: AcpiUtStrupr (strupr)
216 *
217 * PARAMETERS: SrcString - The source string to convert
218 *
219 * RETURN: None
220 *
221 * DESCRIPTION: Convert string to uppercase
222 *
223 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
224 *
225 ******************************************************************************/
226
227 void
228 AcpiUtStrupr (
229 char *SrcString)
230 {
231 char *String;
232
233
234 ACPI_FUNCTION_ENTRY ();
235
236
237 if (!SrcString)
238 {
239 return;
240 }
241
242 /* Walk entire string, uppercasing the letters */
243
244 for (String = SrcString; *String; String++)
245 {
246 *String = (char) ACPI_TOUPPER (*String);
247 }
248
249 return;
250 }
251
252
253 /*******************************************************************************
254 *
255 * FUNCTION: AcpiUtStrtoul64
256 *
257 * PARAMETERS: String - Null terminated string
258 * Base - Radix of the string: 16 or ACPI_ANY_BASE;
259 * ACPI_ANY_BASE means 'in behalf of ToInteger'
260 * RetInteger - Where the converted integer is returned
261 *
262 * RETURN: Status and Converted value
263 *
264 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
265 * 32-bit or 64-bit conversion, depending on the current mode
266 * of the interpreter.
267 * NOTE: Does not support Octal strings, not needed.
268 *
269 ******************************************************************************/
270
271 ACPI_STATUS
272 AcpiUtStrtoul64 (
273 char *String,
274 UINT32 Base,
275 UINT64 *RetInteger)
276 {
277 UINT32 ThisDigit = 0;
278 UINT64 ReturnValue = 0;
279 UINT64 Quotient;
280 UINT64 Dividend;
281 UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE);
282 UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4);
283 UINT8 ValidDigits = 0;
284 UINT8 SignOf0x = 0;
285 UINT8 Term = 0;
286
287
288 ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
289
290
291 switch (Base)
292 {
293 case ACPI_ANY_BASE:
294 case 16:
295
296 break;
297
298 default:
299
300 /* Invalid Base */
301
302 return_ACPI_STATUS (AE_BAD_PARAMETER);
303 }
304
305 if (!String)
306 {
307 goto ErrorExit;
308 }
309
310 /* Skip over any white space in the buffer */
311
312 while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
313 {
314 String++;
315 }
316
317 if (ToIntegerOp)
318 {
319 /*
320 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
321 * We need to determine if it is decimal or hexadecimal.
322 */
323 if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
324 {
325 SignOf0x = 1;
326 Base = 16;
327
328 /* Skip over the leading '0x' */
329 String += 2;
330 }
331 else
332 {
333 Base = 10;
334 }
335 }
336
337 /* Any string left? Check that '0x' is not followed by white space. */
338
339 if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
340 {
341 if (ToIntegerOp)
342 {
343 goto ErrorExit;
344 }
345 else
346 {
347 goto AllDone;
348 }
349 }
350
351 /*
352 * Perform a 32-bit or 64-bit conversion, depending upon the current
353 * execution mode of the interpreter
354 */
355 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
356
357 /* Main loop: convert the string to a 32- or 64-bit integer */
358
359 while (*String)
360 {
361 if (ACPI_IS_DIGIT (*String))
362 {
363 /* Convert ASCII 0-9 to Decimal value */
364
365 ThisDigit = ((UINT8) *String) - '0';
366 }
367 else if (Base == 10)
368 {
369 /* Digit is out of range; possible in ToInteger case only */
370
371 Term = 1;
372 }
373 else
374 {
375 ThisDigit = (UINT8) ACPI_TOUPPER (*String);
376 if (ACPI_IS_XDIGIT ((char) ThisDigit))
377 {
378 /* Convert ASCII Hex char to value */
379
380 ThisDigit = ThisDigit - 'A' + 10;
381 }
382 else
383 {
384 Term = 1;
385 }
386 }
387
388 if (Term)
389 {
390 if (ToIntegerOp)
391 {
392 goto ErrorExit;
393 }
394 else
395 {
396 break;
397 }
398 }
399 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
400 {
401 /* Skip zeros */
402 String++;
403 continue;
404 }
405
406 ValidDigits++;
407
408 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
409 {
410 /*
411 * This is ToInteger operation case.
412 * No any restrictions for string-to-integer conversion,
413 * see ACPI spec.
414 */
415 goto ErrorExit;
416 }
417
418 /* Divide the digit into the correct position */
419
420 (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
421 Base, &Quotient, NULL);
422
423 if (ReturnValue > Quotient)
424 {
425 if (ToIntegerOp)
426 {
427 goto ErrorExit;
428 }
429 else
430 {
431 break;
432 }
433 }
434
435 ReturnValue *= Base;
436 ReturnValue += ThisDigit;
437 String++;
438 }
439
440 /* All done, normal exit */
441
442 AllDone:
443
444 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
445 ACPI_FORMAT_UINT64 (ReturnValue)));
446
447 *RetInteger = ReturnValue;
448 return_ACPI_STATUS (AE_OK);
449
450
451 ErrorExit:
452 /* Base was set/validated above */
453
454 if (Base == 10)
455 {
456 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
457 }
458 else
459 {
460 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
461 }
462 }
463
464
465 /*******************************************************************************
466 *
467 * FUNCTION: AcpiUtPrintString
468 *
469 * PARAMETERS: String - Null terminated ASCII string
470 * MaxLength - Maximum output length. Used to constrain the
471 * length of strings during debug output only.
472 *
473 * RETURN: None
474 *
475 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
476 * sequences.
477 *
478 ******************************************************************************/
479
480 void
481 AcpiUtPrintString (
482 char *String,
483 UINT16 MaxLength)
484 {
485 UINT32 i;
486
487
488 if (!String)
489 {
490 AcpiOsPrintf ("<\"NULL STRING PTR\">");
491 return;
492 }
493
494 AcpiOsPrintf ("\"");
495 for (i = 0; (i < MaxLength) && String[i]; i++)
496 {
497 /* Escape sequences */
498
499 switch (String[i])
500 {
501 case 0x07:
502
503 AcpiOsPrintf ("\\a"); /* BELL */
504 break;
505
506 case 0x08:
507
508 AcpiOsPrintf ("\\b"); /* BACKSPACE */
509 break;
510
511 case 0x0C:
512
513 AcpiOsPrintf ("\\f"); /* FORMFEED */
514 break;
515
516 case 0x0A:
517
518 AcpiOsPrintf ("\\n"); /* LINEFEED */
519 break;
520
521 case 0x0D:
522
523 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/
524 break;
525
526 case 0x09:
527
528 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */
529 break;
530
531 case 0x0B:
532
533 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */
534 break;
535
536 case '\'': /* Single Quote */
537 case '\"': /* Double Quote */
538 case '\\': /* Backslash */
539
540 AcpiOsPrintf ("\\%c", (int) String[i]);
541 break;
542
543 default:
544
545 /* Check for printable character or hex escape */
546
547 if (ACPI_IS_PRINT (String[i]))
548 {
549 /* This is a normal character */
550
551 AcpiOsPrintf ("%c", (int) String[i]);
552 }
553 else
554 {
555 /* All others will be Hex escapes */
556
557 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
558 }
559 break;
560 }
561 }
562 AcpiOsPrintf ("\"");
563
564 if (i == MaxLength && String[i])
565 {
566 AcpiOsPrintf ("...");
567 }
568 }
569
570
571 /*******************************************************************************
572 *
573 * FUNCTION: AcpiUtValidAcpiChar
574 *
575 * PARAMETERS: Char - The character to be examined
576 * Position - Byte position (0-3)
577 *
578 * RETURN: TRUE if the character is valid, FALSE otherwise
579 *
580 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
581 * 1) Upper case alpha
582 * 2) numeric
583 * 3) underscore
584 *
585 * We allow a '!' as the last character because of the ASF! table
586 *
587 ******************************************************************************/
588
589 BOOLEAN
590 AcpiUtValidAcpiChar (
591 char Character,
592 UINT32 Position)
593 {
594
595 if (!((Character >= 'A' && Character <= 'Z') ||
596 (Character >= '0' && Character <= '9') ||
597 (Character == '_')))
598 {
599 /* Allow a '!' in the last position */
600
601 if (Character == '!' && Position == 3)
602 {
603 return (TRUE);
604 }
605
606 return (FALSE);
607 }
608
609 return (TRUE);
610 }
611
612
613 /*******************************************************************************
614 *
615 * FUNCTION: AcpiUtValidAcpiName
616 *
617 * PARAMETERS: Name - The name to be examined. Does not have to
618 * be NULL terminated string.
619 *
620 * RETURN: TRUE if the name is valid, FALSE otherwise
621 *
622 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
623 * 1) Upper case alpha
624 * 2) numeric
625 * 3) underscore
626 *
627 ******************************************************************************/
628
629 BOOLEAN
630 AcpiUtValidAcpiName (
631 char *Name)
632 {
633 UINT32 i;
634
635
636 ACPI_FUNCTION_ENTRY ();
637
638
639 for (i = 0; i < ACPI_NAME_SIZE; i++)
640 {
641 if (!AcpiUtValidAcpiChar (Name[i], i))
642 {
643 return (FALSE);
644 }
645 }
646
647 return (TRUE);
648 }
649
650
651 /*******************************************************************************
652 *
653 * FUNCTION: AcpiUtRepairName
654 *
655 * PARAMETERS: Name - The ACPI name to be repaired
656 *
657 * RETURN: Repaired version of the name
658 *
659 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
660 * return the new name. NOTE: the Name parameter must reside in
661 * read/write memory, cannot be a const.
662 *
663 * An ACPI Name must consist of valid ACPI characters. We will repair the name
664 * if necessary because we don't want to abort because of this, but we want
665 * all namespace names to be printable. A warning message is appropriate.
666 *
667 * This issue came up because there are in fact machines that exhibit
668 * this problem, and we want to be able to enable ACPI support for them,
669 * even though there are a few bad names.
670 *
671 ******************************************************************************/
672
673 void
674 AcpiUtRepairName (
675 char *Name)
676 {
677 UINT32 i;
678 BOOLEAN FoundBadChar = FALSE;
679 UINT32 OriginalName;
680
681
682 ACPI_FUNCTION_NAME (UtRepairName);
683
684
685 ACPI_MOVE_NAME (&OriginalName, Name);
686
687 /* Check each character in the name */
688
689 for (i = 0; i < ACPI_NAME_SIZE; i++)
690 {
691 if (AcpiUtValidAcpiChar (Name[i], i))
692 {
693 continue;
694 }
695
696 /*
697 * Replace a bad character with something printable, yet technically
698 * still invalid. This prevents any collisions with existing "good"
699 * names in the namespace.
700 */
701 Name[i] = '*';
702 FoundBadChar = TRUE;
703 }
704
705 if (FoundBadChar)
706 {
707 /* Report warning only if in strict mode or debug mode */
708
709 if (!AcpiGbl_EnableInterpreterSlack)
710 {
711 ACPI_WARNING ((AE_INFO,
712 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
713 OriginalName, Name));
714 }
715 else
716 {
717 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
718 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
719 OriginalName, Name));
720 }
721 }
722 }
723
724
725 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
726 /*******************************************************************************
727 *
728 * FUNCTION: UtConvertBackslashes
729 *
730 * PARAMETERS: Pathname - File pathname string to be converted
731 *
732 * RETURN: Modifies the input Pathname
733 *
734 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
735 * the entire input file pathname string.
736 *
737 ******************************************************************************/
738
739 void
740 UtConvertBackslashes (
741 char *Pathname)
742 {
743
744 if (!Pathname)
745 {
746 return;
747 }
748
749 while (*Pathname)
750 {
751 if (*Pathname == '\\')
752 {
753 *Pathname = '/';
754 }
755
756 Pathname++;
757 }
758 }
759 #endif
760
761 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
762 /*******************************************************************************
763 *
764 * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
765 *
766 * PARAMETERS: Adds a "DestSize" parameter to each of the standard string
767 * functions. This is the size of the Destination buffer.
768 *
769 * RETURN: TRUE if the operation would overflow the destination buffer.
770 *
771 * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
772 * the result of the operation will not overflow the output string
773 * buffer.
774 *
775 * NOTE: These functions are typically only helpful for processing
776 * user input and command lines. For most ACPICA code, the
777 * required buffer length is precisely calculated before buffer
778 * allocation, so the use of these functions is unnecessary.
779 *
780 ******************************************************************************/
781
782 BOOLEAN
783 AcpiUtSafeStrcpy (
784 char *Dest,
785 ACPI_SIZE DestSize,
786 char *Source)
787 {
788
789 if (ACPI_STRLEN (Source) >= DestSize)
790 {
791 return (TRUE);
792 }
793
794 ACPI_STRCPY (Dest, Source);
795 return (FALSE);
796 }
797
798 BOOLEAN
799 AcpiUtSafeStrcat (
800 char *Dest,
801 ACPI_SIZE DestSize,
802 char *Source)
803 {
804
805 if ((ACPI_STRLEN (Dest) + ACPI_STRLEN (Source)) >= DestSize)
806 {
807 return (TRUE);
808 }
809
810 ACPI_STRCAT (Dest, Source);
811 return (FALSE);
812 }
813
814 BOOLEAN
815 AcpiUtSafeStrncat (
816 char *Dest,
817 ACPI_SIZE DestSize,
818 char *Source,
819 ACPI_SIZE MaxTransferLength)
820 {
821 ACPI_SIZE ActualTransferLength;
822
823
824 ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source));
825
826 if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize)
827 {
828 return (TRUE);
829 }
830
831 ACPI_STRNCAT (Dest, Source, MaxTransferLength);
832 return (FALSE);
833 }
834 #endif