1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2018, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utprint")
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
60 /* Local prototypes */
63 AcpiUtBoundStringLength (
68 AcpiUtBoundStringOutput (
91 /*******************************************************************************
93 * FUNCTION: AcpiUtBoundStringLength
95 * PARAMETERS: String - String with boundary
96 * Count - Boundary of the string
98 * RETURN: Length of the string. Less than or equal to Count.
100 * DESCRIPTION: Calculate the length of a string with boundary.
102 ******************************************************************************/
105 AcpiUtBoundStringLength (
112 while (*String
&& Count
)
123 /*******************************************************************************
125 * FUNCTION: AcpiUtBoundStringOutput
127 * PARAMETERS: String - String with boundary
128 * End - Boundary of the string
129 * c - Character to be output to the string
131 * RETURN: Updated position for next valid character
133 * DESCRIPTION: Output a character into a string with boundary check.
135 ******************************************************************************/
138 AcpiUtBoundStringOutput (
154 /*******************************************************************************
156 * FUNCTION: AcpiUtPutNumber
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
163 * RETURN: Updated position for next valid character
165 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
166 * reversed ordered number without the trailing zero.
168 ******************************************************************************/
183 Digits
= Upper
? AcpiGbl_UpperHexDigits
: AcpiGbl_LowerHexDigits
;
193 (void) AcpiUtDivide (Number
, Base
, &Number
, &DigitIndex
);
194 *(Pos
++) = Digits
[DigitIndex
];
198 /* *(Pos++) = '0'; */
203 /*******************************************************************************
205 * FUNCTION: AcpiUtScanNumber
207 * PARAMETERS: String - String buffer
208 * NumberPtr - Where the number is returned
210 * RETURN: Updated position for next valid character
212 * DESCRIPTION: Scan a string for a decimal integer.
214 ******************************************************************************/
224 while (isdigit ((int) *String
))
226 AcpiUtShortMultiply (Number
, 10, &Number
);
227 Number
+= *(String
++) - '0';
235 /*******************************************************************************
237 * FUNCTION: AcpiUtPrintNumber
239 * PARAMETERS: String - String buffer
240 * Number - The number to be converted
242 * RETURN: Updated position for next valid character
244 * DESCRIPTION: Print a decimal integer into a string.
246 ******************************************************************************/
253 char AsciiString
[20];
258 Pos1
= AcpiUtPutNumber (AsciiString
, Number
, 10, FALSE
);
261 while (Pos1
!= AsciiString
)
263 *(Pos2
++) = *(--Pos1
);
271 /*******************************************************************************
273 * FUNCTION: AcpiUtFormatNumber
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
283 * RETURN: Updated position for next valid character
285 * DESCRIPTION: Print an integer into a string with any base and any precision.
287 ******************************************************************************/
305 char ReversedString
[66];
308 /* Parameter validation */
310 if (Base
< 2 || Base
> 16)
315 if (Type
& ACPI_FORMAT_LEFT
)
317 Type
&= ~ACPI_FORMAT_ZERO
;
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' : ' ';
324 /* Calculate size according to sign and prefix */
327 if (Type
& ACPI_FORMAT_SIGN
)
329 if ((INT64
) Number
< 0)
332 Number
= - (INT64
) Number
;
335 else if (Type
& ACPI_FORMAT_SIGN_PLUS
)
340 else if (Type
& ACPI_FORMAT_SIGN_PLUS_SPACE
)
355 /* Generate full string in reverse order */
357 Pos
= AcpiUtPutNumber (ReversedString
, Number
, Base
, Upper
);
358 i
= (INT32
) ACPI_PTR_DIFF (Pos
, ReversedString
);
360 /* Printing 100 using %2d gives "100", not "00" */
369 /* Output the string */
371 if (!(Type
& (ACPI_FORMAT_ZERO
| ACPI_FORMAT_LEFT
)))
375 String
= AcpiUtBoundStringOutput (String
, End
, ' ');
380 String
= AcpiUtBoundStringOutput (String
, End
, Sign
);
384 String
= AcpiUtBoundStringOutput (String
, End
, '0');
387 String
= AcpiUtBoundStringOutput (
388 String
, End
, Upper
? 'X' : 'x');
391 if (!(Type
& ACPI_FORMAT_LEFT
))
395 String
= AcpiUtBoundStringOutput (String
, End
, Zero
);
399 while (i
<= --Precision
)
401 String
= AcpiUtBoundStringOutput (String
, End
, '0');
405 String
= AcpiUtBoundStringOutput (String
, End
,
410 String
= AcpiUtBoundStringOutput (String
, End
, ' ');
417 /*******************************************************************************
419 * FUNCTION: vsnprintf
421 * PARAMETERS: String - String with boundary
422 * Size - Boundary of the string
423 * Format - Standard printf format
424 * Args - Argument list
426 * RETURN: Number of bytes actually written.
428 * DESCRIPTION: Formatted output to a string using argument list pointer.
430 ******************************************************************************/
457 for (; *Format
; ++Format
)
461 Pos
= AcpiUtBoundStringOutput (Pos
, End
, *Format
);
475 Type
|= ACPI_FORMAT_PREFIX
;
477 else if (*Format
== '0')
479 Type
|= ACPI_FORMAT_ZERO
;
481 else if (*Format
== '+')
483 Type
|= ACPI_FORMAT_SIGN_PLUS
;
485 else if (*Format
== ' ')
487 Type
|= ACPI_FORMAT_SIGN_PLUS_SPACE
;
489 else if (*Format
== '-')
491 Type
|= ACPI_FORMAT_LEFT
;
503 if (isdigit ((int) *Format
))
505 Format
= AcpiUtScanNumber (Format
, &Number
);
506 Width
= (INT32
) Number
;
508 else if (*Format
== '*')
511 Width
= va_arg (Args
, int);
515 Type
|= ACPI_FORMAT_LEFT
;
519 /* Process precision */
525 if (isdigit ((int) *Format
))
527 Format
= AcpiUtScanNumber (Format
, &Number
);
528 Precision
= (INT32
) Number
;
530 else if (*Format
== '*')
533 Precision
= va_arg (Args
, int);
542 /* Process qualifier */
545 if (*Format
== 'h' || *Format
== 'l' || *Format
== 'L')
550 if (Qualifier
== 'l' && *Format
== 'l')
561 Pos
= AcpiUtBoundStringOutput (Pos
, End
, '%');
566 if (!(Type
& ACPI_FORMAT_LEFT
))
570 Pos
= AcpiUtBoundStringOutput (Pos
, End
, ' ');
574 c
= (char) va_arg (Args
, int);
575 Pos
= AcpiUtBoundStringOutput (Pos
, End
, c
);
579 Pos
= AcpiUtBoundStringOutput (Pos
, End
, ' ');
585 s
= va_arg (Args
, char *);
590 Length
= (INT32
) AcpiUtBoundStringLength (s
, Precision
);
591 if (!(Type
& ACPI_FORMAT_LEFT
))
593 while (Length
< Width
--)
595 Pos
= AcpiUtBoundStringOutput (Pos
, End
, ' ');
599 for (i
= 0; i
< Length
; ++i
)
601 Pos
= AcpiUtBoundStringOutput (Pos
, End
, *s
);
605 while (Length
< Width
--)
607 Pos
= AcpiUtBoundStringOutput (Pos
, End
, ' ');
618 Type
|= ACPI_FORMAT_UPPER
;
629 Type
|= ACPI_FORMAT_SIGN
;
639 Width
= 2 * sizeof (void *);
640 Type
|= ACPI_FORMAT_ZERO
;
643 p
= va_arg (Args
, void *);
644 Pos
= AcpiUtFormatNumber (
645 Pos
, End
, ACPI_TO_INTEGER (p
), 16, Width
, Precision
, Type
);
650 Pos
= AcpiUtBoundStringOutput (Pos
, End
, '%');
653 Pos
= AcpiUtBoundStringOutput (Pos
, End
, *Format
);
662 if (Qualifier
== 'L')
664 Number
= va_arg (Args
, UINT64
);
665 if (Type
& ACPI_FORMAT_SIGN
)
667 Number
= (INT64
) Number
;
670 else if (Qualifier
== 'l')
672 Number
= va_arg (Args
, unsigned long);
673 if (Type
& ACPI_FORMAT_SIGN
)
675 Number
= (INT32
) Number
;
678 else if (Qualifier
== 'h')
680 Number
= (UINT16
) va_arg (Args
, int);
681 if (Type
& ACPI_FORMAT_SIGN
)
683 Number
= (INT16
) Number
;
688 Number
= va_arg (Args
, unsigned int);
689 if (Type
& ACPI_FORMAT_SIGN
)
691 Number
= (signed int) Number
;
695 Pos
= AcpiUtFormatNumber (Pos
, End
, Number
, Base
,
696 Width
, Precision
, Type
);
711 return ((int) ACPI_PTR_DIFF (Pos
, String
));
715 /*******************************************************************************
719 * PARAMETERS: String - String with boundary
720 * Size - Boundary of the string
721 * Format, ... - Standard printf format
723 * RETURN: Number of bytes actually written.
725 * DESCRIPTION: Formatted output to a string.
727 ******************************************************************************/
740 va_start (Args
, Format
);
741 Length
= vsnprintf (String
, Size
, Format
, Args
);
748 /*******************************************************************************
752 * PARAMETERS: String - String with boundary
753 * Format, ... - Standard printf format
755 * RETURN: Number of bytes actually written.
757 * DESCRIPTION: Formatted output to a string.
759 ******************************************************************************/
771 va_start (Args
, Format
);
772 Length
= vsnprintf (String
, ACPI_UINT32_MAX
, Format
, Args
);
779 #ifdef ACPI_APPLICATION
780 /*******************************************************************************
784 * PARAMETERS: Format - Standard printf format
785 * Args - Argument list
787 * RETURN: Number of bytes actually written.
789 * DESCRIPTION: Formatted output to stdout using argument list pointer.
791 ******************************************************************************/
798 ACPI_CPU_FLAGS Flags
;
802 Flags
= AcpiOsAcquireLock (AcpiGbl_PrintLock
);
803 Length
= vsnprintf (AcpiGbl_PrintBuffer
,
804 sizeof (AcpiGbl_PrintBuffer
), Format
, Args
);
806 (void) fwrite (AcpiGbl_PrintBuffer
, Length
, 1, ACPI_FILE_OUT
);
807 AcpiOsReleaseLock (AcpiGbl_PrintLock
, Flags
);
813 /*******************************************************************************
817 * PARAMETERS: Format, ... - Standard printf format
819 * RETURN: Number of bytes actually written.
821 * DESCRIPTION: Formatted output to stdout.
823 ******************************************************************************/
834 va_start (Args
, Format
);
835 Length
= vprintf (Format
, Args
);
842 /*******************************************************************************
846 * PARAMETERS: File - File descriptor
847 * Format - Standard printf format
848 * Args - Argument list
850 * RETURN: Number of bytes actually written.
852 * DESCRIPTION: Formatted output to a file using argument list pointer.
854 ******************************************************************************/
862 ACPI_CPU_FLAGS Flags
;
866 Flags
= AcpiOsAcquireLock (AcpiGbl_PrintLock
);
867 Length
= vsnprintf (AcpiGbl_PrintBuffer
,
868 sizeof (AcpiGbl_PrintBuffer
), Format
, Args
);
870 (void) fwrite (AcpiGbl_PrintBuffer
, Length
, 1, File
);
871 AcpiOsReleaseLock (AcpiGbl_PrintLock
, Flags
);
877 /*******************************************************************************
881 * PARAMETERS: File - File descriptor
882 * Format, ... - Standard printf format
884 * RETURN: Number of bytes actually written.
886 * DESCRIPTION: Formatted output to a file.
888 ******************************************************************************/
900 va_start (Args
, Format
);
901 Length
= vfprintf (File
, Format
, Args
);