1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, 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
))
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
= 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: AcpiUtVsnprintf
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
= 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
;
628 Type
|= ACPI_FORMAT_SIGN
;
638 Width
= 2 * sizeof (void *);
639 Type
|= ACPI_FORMAT_ZERO
;
642 p
= va_arg (Args
, void *);
643 Pos
= AcpiUtFormatNumber (
644 Pos
, End
, ACPI_TO_INTEGER (p
), 16, Width
, Precision
, Type
);
649 Pos
= AcpiUtBoundStringOutput (Pos
, End
, '%');
652 Pos
= AcpiUtBoundStringOutput (Pos
, End
, *Format
);
661 if (Qualifier
== 'L')
663 Number
= va_arg (Args
, UINT64
);
664 if (Type
& ACPI_FORMAT_SIGN
)
666 Number
= (INT64
) Number
;
669 else if (Qualifier
== 'l')
671 Number
= va_arg (Args
, unsigned long);
672 if (Type
& ACPI_FORMAT_SIGN
)
674 Number
= (INT32
) Number
;
677 else if (Qualifier
== 'h')
679 Number
= (UINT16
) va_arg (Args
, int);
680 if (Type
& ACPI_FORMAT_SIGN
)
682 Number
= (INT16
) Number
;
687 Number
= va_arg (Args
, unsigned int);
688 if (Type
& ACPI_FORMAT_SIGN
)
690 Number
= (signed int) Number
;
694 Pos
= AcpiUtFormatNumber (Pos
, End
, Number
, Base
,
695 Width
, Precision
, Type
);
710 return (ACPI_PTR_DIFF (Pos
, String
));
714 /*******************************************************************************
716 * FUNCTION: AcpiUtSnprintf
718 * PARAMETERS: String - String with boundary
719 * Size - Boundary of the string
720 * Format, ... - Standard printf format
722 * RETURN: Number of bytes actually written.
724 * DESCRIPTION: Formatted output to a string.
726 ******************************************************************************/
739 va_start (Args
, Format
);
740 Length
= AcpiUtVsnprintf (String
, Size
, Format
, Args
);
747 #ifdef ACPI_APPLICATION
748 /*******************************************************************************
750 * FUNCTION: AcpiUtFileVprintf
752 * PARAMETERS: File - File descriptor
753 * Format - Standard printf format
754 * Args - Argument list
756 * RETURN: Number of bytes actually written.
758 * DESCRIPTION: Formatted output to a file using argument list pointer.
760 ******************************************************************************/
768 ACPI_CPU_FLAGS Flags
;
772 Flags
= AcpiOsAcquireLock (AcpiGbl_PrintLock
);
773 Length
= AcpiUtVsnprintf (AcpiGbl_PrintBuffer
,
774 sizeof (AcpiGbl_PrintBuffer
), Format
, Args
);
776 (void) AcpiOsWriteFile (File
, AcpiGbl_PrintBuffer
, Length
, 1);
777 AcpiOsReleaseLock (AcpiGbl_PrintLock
, Flags
);
783 /*******************************************************************************
785 * FUNCTION: AcpiUtFilePrintf
787 * PARAMETERS: File - File descriptor
788 * Format, ... - Standard printf format
790 * RETURN: Number of bytes actually written.
792 * DESCRIPTION: Formatted output to a file.
794 ******************************************************************************/
806 va_start (Args
, Format
);
807 Length
= AcpiUtFileVprintf (File
, Format
, Args
);