[ACPICA] Update to version 20180531. CORE-15222
[reactos.git] / drivers / bus / acpi / acpica / utilities / utprint.c
1 /******************************************************************************
2 *
3 * Module Name: utprint - Formatted printing routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utprint")
49
50
51 #define ACPI_FORMAT_SIGN 0x01
52 #define ACPI_FORMAT_SIGN_PLUS 0x02
53 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
54 #define ACPI_FORMAT_ZERO 0x08
55 #define ACPI_FORMAT_LEFT 0x10
56 #define ACPI_FORMAT_UPPER 0x20
57 #define ACPI_FORMAT_PREFIX 0x40
58
59
60 /* Local prototypes */
61
62 static ACPI_SIZE
63 AcpiUtBoundStringLength (
64 const char *String,
65 ACPI_SIZE Count);
66
67 static char *
68 AcpiUtBoundStringOutput (
69 char *String,
70 const char *End,
71 char c);
72
73 static char *
74 AcpiUtFormatNumber (
75 char *String,
76 char *End,
77 UINT64 Number,
78 UINT8 Base,
79 INT32 Width,
80 INT32 Precision,
81 UINT8 Type);
82
83 static char *
84 AcpiUtPutNumber (
85 char *String,
86 UINT64 Number,
87 UINT8 Base,
88 BOOLEAN Upper);
89
90
91 /*******************************************************************************
92 *
93 * FUNCTION: AcpiUtBoundStringLength
94 *
95 * PARAMETERS: String - String with boundary
96 * Count - Boundary of the string
97 *
98 * RETURN: Length of the string. Less than or equal to Count.
99 *
100 * DESCRIPTION: Calculate the length of a string with boundary.
101 *
102 ******************************************************************************/
103
104 static ACPI_SIZE
105 AcpiUtBoundStringLength (
106 const char *String,
107 ACPI_SIZE Count)
108 {
109 UINT32 Length = 0;
110
111
112 while (*String && Count)
113 {
114 Length++;
115 String++;
116 Count--;
117 }
118
119 return (Length);
120 }
121
122
123 /*******************************************************************************
124 *
125 * FUNCTION: AcpiUtBoundStringOutput
126 *
127 * PARAMETERS: String - String with boundary
128 * End - Boundary of the string
129 * c - Character to be output to the string
130 *
131 * RETURN: Updated position for next valid character
132 *
133 * DESCRIPTION: Output a character into a string with boundary check.
134 *
135 ******************************************************************************/
136
137 static char *
138 AcpiUtBoundStringOutput (
139 char *String,
140 const char *End,
141 char c)
142 {
143
144 if (String < End)
145 {
146 *String = c;
147 }
148
149 ++String;
150 return (String);
151 }
152
153
154 /*******************************************************************************
155 *
156 * FUNCTION: AcpiUtPutNumber
157 *
158 * PARAMETERS: String - Buffer to hold reverse-ordered string
159 * Number - Integer to be converted
160 * Base - Base of the integer
161 * Upper - Whether or not using upper cased digits
162 *
163 * RETURN: Updated position for next valid character
164 *
165 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
166 * reversed ordered number without the trailing zero.
167 *
168 ******************************************************************************/
169
170 static char *
171 AcpiUtPutNumber (
172 char *String,
173 UINT64 Number,
174 UINT8 Base,
175 BOOLEAN Upper)
176 {
177 const char *Digits;
178 UINT64 DigitIndex;
179 char *Pos;
180
181
182 Pos = String;
183 Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits;
184
185 if (Number == 0)
186 {
187 *(Pos++) = '0';
188 }
189 else
190 {
191 while (Number)
192 {
193 (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex);
194 *(Pos++) = Digits[DigitIndex];
195 }
196 }
197
198 /* *(Pos++) = '0'; */
199 return (Pos);
200 }
201
202
203 /*******************************************************************************
204 *
205 * FUNCTION: AcpiUtScanNumber
206 *
207 * PARAMETERS: String - String buffer
208 * NumberPtr - Where the number is returned
209 *
210 * RETURN: Updated position for next valid character
211 *
212 * DESCRIPTION: Scan a string for a decimal integer.
213 *
214 ******************************************************************************/
215
216 const char *
217 AcpiUtScanNumber (
218 const char *String,
219 UINT64 *NumberPtr)
220 {
221 UINT64 Number = 0;
222
223
224 while (isdigit ((int) *String))
225 {
226 AcpiUtShortMultiply (Number, 10, &Number);
227 Number += *(String++) - '0';
228 }
229
230 *NumberPtr = Number;
231 return (String);
232 }
233
234
235 /*******************************************************************************
236 *
237 * FUNCTION: AcpiUtPrintNumber
238 *
239 * PARAMETERS: String - String buffer
240 * Number - The number to be converted
241 *
242 * RETURN: Updated position for next valid character
243 *
244 * DESCRIPTION: Print a decimal integer into a string.
245 *
246 ******************************************************************************/
247
248 const char *
249 AcpiUtPrintNumber (
250 char *String,
251 UINT64 Number)
252 {
253 char AsciiString[20];
254 const char *Pos1;
255 char *Pos2;
256
257
258 Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE);
259 Pos2 = String;
260
261 while (Pos1 != AsciiString)
262 {
263 *(Pos2++) = *(--Pos1);
264 }
265
266 *Pos2 = 0;
267 return (String);
268 }
269
270
271 /*******************************************************************************
272 *
273 * FUNCTION: AcpiUtFormatNumber
274 *
275 * PARAMETERS: String - String buffer with boundary
276 * End - Boundary of the string
277 * Number - The number to be converted
278 * Base - Base of the integer
279 * Width - Field width
280 * Precision - Precision of the integer
281 * Type - Special printing flags
282 *
283 * RETURN: Updated position for next valid character
284 *
285 * DESCRIPTION: Print an integer into a string with any base and any precision.
286 *
287 ******************************************************************************/
288
289 static char *
290 AcpiUtFormatNumber (
291 char *String,
292 char *End,
293 UINT64 Number,
294 UINT8 Base,
295 INT32 Width,
296 INT32 Precision,
297 UINT8 Type)
298 {
299 char *Pos;
300 char Sign;
301 char Zero;
302 BOOLEAN NeedPrefix;
303 BOOLEAN Upper;
304 INT32 i;
305 char ReversedString[66];
306
307
308 /* Parameter validation */
309
310 if (Base < 2 || Base > 16)
311 {
312 return (NULL);
313 }
314
315 if (Type & ACPI_FORMAT_LEFT)
316 {
317 Type &= ~ACPI_FORMAT_ZERO;
318 }
319
320 NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE;
321 Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
322 Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' ';
323
324 /* Calculate size according to sign and prefix */
325
326 Sign = '\0';
327 if (Type & ACPI_FORMAT_SIGN)
328 {
329 if ((INT64) Number < 0)
330 {
331 Sign = '-';
332 Number = - (INT64) Number;
333 Width--;
334 }
335 else if (Type & ACPI_FORMAT_SIGN_PLUS)
336 {
337 Sign = '+';
338 Width--;
339 }
340 else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE)
341 {
342 Sign = ' ';
343 Width--;
344 }
345 }
346 if (NeedPrefix)
347 {
348 Width--;
349 if (Base == 16)
350 {
351 Width--;
352 }
353 }
354
355 /* Generate full string in reverse order */
356
357 Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper);
358 i = (INT32) ACPI_PTR_DIFF (Pos, ReversedString);
359
360 /* Printing 100 using %2d gives "100", not "00" */
361
362 if (i > Precision)
363 {
364 Precision = i;
365 }
366
367 Width -= Precision;
368
369 /* Output the string */
370
371 if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT)))
372 {
373 while (--Width >= 0)
374 {
375 String = AcpiUtBoundStringOutput (String, End, ' ');
376 }
377 }
378 if (Sign)
379 {
380 String = AcpiUtBoundStringOutput (String, End, Sign);
381 }
382 if (NeedPrefix)
383 {
384 String = AcpiUtBoundStringOutput (String, End, '0');
385 if (Base == 16)
386 {
387 String = AcpiUtBoundStringOutput (
388 String, End, Upper ? 'X' : 'x');
389 }
390 }
391 if (!(Type & ACPI_FORMAT_LEFT))
392 {
393 while (--Width >= 0)
394 {
395 String = AcpiUtBoundStringOutput (String, End, Zero);
396 }
397 }
398
399 while (i <= --Precision)
400 {
401 String = AcpiUtBoundStringOutput (String, End, '0');
402 }
403 while (--i >= 0)
404 {
405 String = AcpiUtBoundStringOutput (String, End,
406 ReversedString[i]);
407 }
408 while (--Width >= 0)
409 {
410 String = AcpiUtBoundStringOutput (String, End, ' ');
411 }
412
413 return (String);
414 }
415
416
417 /*******************************************************************************
418 *
419 * FUNCTION: vsnprintf
420 *
421 * PARAMETERS: String - String with boundary
422 * Size - Boundary of the string
423 * Format - Standard printf format
424 * Args - Argument list
425 *
426 * RETURN: Number of bytes actually written.
427 *
428 * DESCRIPTION: Formatted output to a string using argument list pointer.
429 *
430 ******************************************************************************/
431
432 int
433 vsnprintf (
434 char *String,
435 ACPI_SIZE Size,
436 const char *Format,
437 va_list Args)
438 {
439 UINT8 Base;
440 UINT8 Type;
441 INT32 Width;
442 INT32 Precision;
443 char Qualifier;
444 UINT64 Number;
445 char *Pos;
446 char *End;
447 char c;
448 const char *s;
449 const void *p;
450 INT32 Length;
451 int i;
452
453
454 Pos = String;
455 End = String + Size;
456
457 for (; *Format; ++Format)
458 {
459 if (*Format != '%')
460 {
461 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
462 continue;
463 }
464
465 Type = 0;
466 Base = 10;
467
468 /* Process sign */
469
470 do
471 {
472 ++Format;
473 if (*Format == '#')
474 {
475 Type |= ACPI_FORMAT_PREFIX;
476 }
477 else if (*Format == '0')
478 {
479 Type |= ACPI_FORMAT_ZERO;
480 }
481 else if (*Format == '+')
482 {
483 Type |= ACPI_FORMAT_SIGN_PLUS;
484 }
485 else if (*Format == ' ')
486 {
487 Type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
488 }
489 else if (*Format == '-')
490 {
491 Type |= ACPI_FORMAT_LEFT;
492 }
493 else
494 {
495 break;
496 }
497
498 } while (1);
499
500 /* Process width */
501
502 Width = -1;
503 if (isdigit ((int) *Format))
504 {
505 Format = AcpiUtScanNumber (Format, &Number);
506 Width = (INT32) Number;
507 }
508 else if (*Format == '*')
509 {
510 ++Format;
511 Width = va_arg (Args, int);
512 if (Width < 0)
513 {
514 Width = -Width;
515 Type |= ACPI_FORMAT_LEFT;
516 }
517 }
518
519 /* Process precision */
520
521 Precision = -1;
522 if (*Format == '.')
523 {
524 ++Format;
525 if (isdigit ((int) *Format))
526 {
527 Format = AcpiUtScanNumber (Format, &Number);
528 Precision = (INT32) Number;
529 }
530 else if (*Format == '*')
531 {
532 ++Format;
533 Precision = va_arg (Args, int);
534 }
535
536 if (Precision < 0)
537 {
538 Precision = 0;
539 }
540 }
541
542 /* Process qualifier */
543
544 Qualifier = -1;
545 if (*Format == 'h' || *Format == 'l' || *Format == 'L')
546 {
547 Qualifier = *Format;
548 ++Format;
549
550 if (Qualifier == 'l' && *Format == 'l')
551 {
552 Qualifier = 'L';
553 ++Format;
554 }
555 }
556
557 switch (*Format)
558 {
559 case '%':
560
561 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
562 continue;
563
564 case 'c':
565
566 if (!(Type & ACPI_FORMAT_LEFT))
567 {
568 while (--Width > 0)
569 {
570 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
571 }
572 }
573
574 c = (char) va_arg (Args, int);
575 Pos = AcpiUtBoundStringOutput (Pos, End, c);
576
577 while (--Width > 0)
578 {
579 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
580 }
581 continue;
582
583 case 's':
584
585 s = va_arg (Args, char *);
586 if (!s)
587 {
588 s = "<NULL>";
589 }
590 Length = (INT32) AcpiUtBoundStringLength (s, Precision);
591 if (!(Type & ACPI_FORMAT_LEFT))
592 {
593 while (Length < Width--)
594 {
595 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
596 }
597 }
598
599 for (i = 0; i < Length; ++i)
600 {
601 Pos = AcpiUtBoundStringOutput (Pos, End, *s);
602 ++s;
603 }
604
605 while (Length < Width--)
606 {
607 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
608 }
609 continue;
610
611 case 'o':
612
613 Base = 8;
614 break;
615
616 case 'X':
617
618 Type |= ACPI_FORMAT_UPPER;
619 /* FALLTHROUGH */
620
621 case 'x':
622
623 Base = 16;
624 break;
625
626 case 'd':
627 case 'i':
628
629 Type |= ACPI_FORMAT_SIGN;
630
631 case 'u':
632
633 break;
634
635 case 'p':
636
637 if (Width == -1)
638 {
639 Width = 2 * sizeof (void *);
640 Type |= ACPI_FORMAT_ZERO;
641 }
642
643 p = va_arg (Args, void *);
644 Pos = AcpiUtFormatNumber (
645 Pos, End, ACPI_TO_INTEGER (p), 16, Width, Precision, Type);
646 continue;
647
648 default:
649
650 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
651 if (*Format)
652 {
653 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
654 }
655 else
656 {
657 --Format;
658 }
659 continue;
660 }
661
662 if (Qualifier == 'L')
663 {
664 Number = va_arg (Args, UINT64);
665 if (Type & ACPI_FORMAT_SIGN)
666 {
667 Number = (INT64) Number;
668 }
669 }
670 else if (Qualifier == 'l')
671 {
672 Number = va_arg (Args, unsigned long);
673 if (Type & ACPI_FORMAT_SIGN)
674 {
675 Number = (INT32) Number;
676 }
677 }
678 else if (Qualifier == 'h')
679 {
680 Number = (UINT16) va_arg (Args, int);
681 if (Type & ACPI_FORMAT_SIGN)
682 {
683 Number = (INT16) Number;
684 }
685 }
686 else
687 {
688 Number = va_arg (Args, unsigned int);
689 if (Type & ACPI_FORMAT_SIGN)
690 {
691 Number = (signed int) Number;
692 }
693 }
694
695 Pos = AcpiUtFormatNumber (Pos, End, Number, Base,
696 Width, Precision, Type);
697 }
698
699 if (Size > 0)
700 {
701 if (Pos < End)
702 {
703 *Pos = '\0';
704 }
705 else
706 {
707 End[-1] = '\0';
708 }
709 }
710
711 return ((int) ACPI_PTR_DIFF (Pos, String));
712 }
713
714
715 /*******************************************************************************
716 *
717 * FUNCTION: snprintf
718 *
719 * PARAMETERS: String - String with boundary
720 * Size - Boundary of the string
721 * Format, ... - Standard printf format
722 *
723 * RETURN: Number of bytes actually written.
724 *
725 * DESCRIPTION: Formatted output to a string.
726 *
727 ******************************************************************************/
728
729 int
730 snprintf (
731 char *String,
732 ACPI_SIZE Size,
733 const char *Format,
734 ...)
735 {
736 va_list Args;
737 int Length;
738
739
740 va_start (Args, Format);
741 Length = vsnprintf (String, Size, Format, Args);
742 va_end (Args);
743
744 return (Length);
745 }
746
747
748 /*******************************************************************************
749 *
750 * FUNCTION: sprintf
751 *
752 * PARAMETERS: String - String with boundary
753 * Format, ... - Standard printf format
754 *
755 * RETURN: Number of bytes actually written.
756 *
757 * DESCRIPTION: Formatted output to a string.
758 *
759 ******************************************************************************/
760
761 int
762 sprintf (
763 char *String,
764 const char *Format,
765 ...)
766 {
767 va_list Args;
768 int Length;
769
770
771 va_start (Args, Format);
772 Length = vsnprintf (String, ACPI_UINT32_MAX, Format, Args);
773 va_end (Args);
774
775 return (Length);
776 }
777
778
779 #ifdef ACPI_APPLICATION
780 /*******************************************************************************
781 *
782 * FUNCTION: vprintf
783 *
784 * PARAMETERS: Format - Standard printf format
785 * Args - Argument list
786 *
787 * RETURN: Number of bytes actually written.
788 *
789 * DESCRIPTION: Formatted output to stdout using argument list pointer.
790 *
791 ******************************************************************************/
792
793 int
794 vprintf (
795 const char *Format,
796 va_list Args)
797 {
798 ACPI_CPU_FLAGS Flags;
799 int Length;
800
801
802 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
803 Length = vsnprintf (AcpiGbl_PrintBuffer,
804 sizeof (AcpiGbl_PrintBuffer), Format, Args);
805
806 (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, ACPI_FILE_OUT);
807 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
808
809 return (Length);
810 }
811
812
813 /*******************************************************************************
814 *
815 * FUNCTION: printf
816 *
817 * PARAMETERS: Format, ... - Standard printf format
818 *
819 * RETURN: Number of bytes actually written.
820 *
821 * DESCRIPTION: Formatted output to stdout.
822 *
823 ******************************************************************************/
824
825 int
826 printf (
827 const char *Format,
828 ...)
829 {
830 va_list Args;
831 int Length;
832
833
834 va_start (Args, Format);
835 Length = vprintf (Format, Args);
836 va_end (Args);
837
838 return (Length);
839 }
840
841
842 /*******************************************************************************
843 *
844 * FUNCTION: vfprintf
845 *
846 * PARAMETERS: File - File descriptor
847 * Format - Standard printf format
848 * Args - Argument list
849 *
850 * RETURN: Number of bytes actually written.
851 *
852 * DESCRIPTION: Formatted output to a file using argument list pointer.
853 *
854 ******************************************************************************/
855
856 int
857 vfprintf (
858 FILE *File,
859 const char *Format,
860 va_list Args)
861 {
862 ACPI_CPU_FLAGS Flags;
863 int Length;
864
865
866 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
867 Length = vsnprintf (AcpiGbl_PrintBuffer,
868 sizeof (AcpiGbl_PrintBuffer), Format, Args);
869
870 (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, File);
871 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
872
873 return (Length);
874 }
875
876
877 /*******************************************************************************
878 *
879 * FUNCTION: fprintf
880 *
881 * PARAMETERS: File - File descriptor
882 * Format, ... - Standard printf format
883 *
884 * RETURN: Number of bytes actually written.
885 *
886 * DESCRIPTION: Formatted output to a file.
887 *
888 ******************************************************************************/
889
890 int
891 fprintf (
892 FILE *File,
893 const char *Format,
894 ...)
895 {
896 va_list Args;
897 int Length;
898
899
900 va_start (Args, Format);
901 Length = vfprintf (File, Format, Args);
902 va_end (Args);
903
904 return (Length);
905 }
906 #endif