1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, 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 (
93 static const char AcpiGbl_LowerHexDigits[] = "0123456789abcdef";
94 static const char AcpiGbl_UpperHexDigits[] = "0123456789ABCDEF";
97 /*******************************************************************************
99 * FUNCTION: AcpiUtBoundStringLength
101 * PARAMETERS: String - String with boundary
102 * Count - Boundary of the string
104 * RETURN: Length of the string. Less than or equal to Count.
106 * DESCRIPTION: Calculate the length of a string with boundary.
108 ******************************************************************************/
111 AcpiUtBoundStringLength (
118 while (*String && Count)
129 /*******************************************************************************
131 * FUNCTION: AcpiUtBoundStringOutput
133 * PARAMETERS: String - String with boundary
134 * End - Boundary of the string
135 * c - Character to be output to the string
137 * RETURN: Updated position for next valid character
139 * DESCRIPTION: Output a character into a string with boundary check.
141 ******************************************************************************/
144 AcpiUtBoundStringOutput (
160 /*******************************************************************************
162 * FUNCTION: AcpiUtPutNumber
164 * PARAMETERS: String - Buffer to hold reverse-ordered string
165 * Number - Integer to be converted
166 * Base - Base of the integer
167 * Upper - Whether or not using upper cased digits
169 * RETURN: Updated position for next valid character
171 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
172 * reversed ordered number without the trailing zero.
174 ******************************************************************************/
189 Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits;
199 (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex);
200 *(Pos++) = Digits[DigitIndex];
204 /* *(Pos++) = '0'; */
209 /*******************************************************************************
211 * FUNCTION: AcpiUtScanNumber
213 * PARAMETERS: String - String buffer
214 * NumberPtr - Where the number is returned
216 * RETURN: Updated position for next valid character
218 * DESCRIPTION: Scan a string for a decimal integer.
220 ******************************************************************************/
230 while (isdigit ((int) *String))
233 Number += *(String++) - '0';
241 /*******************************************************************************
243 * FUNCTION: AcpiUtPrintNumber
245 * PARAMETERS: String - String buffer
246 * Number - The number to be converted
248 * RETURN: Updated position for next valid character
250 * DESCRIPTION: Print a decimal integer into a string.
252 ******************************************************************************/
259 char AsciiString[20];
264 Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE);
267 while (Pos1 != AsciiString)
269 *(Pos2++) = *(--Pos1);
277 /*******************************************************************************
279 * FUNCTION: AcpiUtFormatNumber
281 * PARAMETERS: String - String buffer with boundary
282 * End - Boundary of the string
283 * Number - The number to be converted
284 * Base - Base of the integer
285 * Width - Field width
286 * Precision - Precision of the integer
287 * Type - Special printing flags
289 * RETURN: Updated position for next valid character
291 * DESCRIPTION: Print an integer into a string with any base and any precision.
293 ******************************************************************************/
311 char ReversedString[66];
314 /* Parameter validation */
316 if (Base < 2 || Base > 16)
321 if (Type & ACPI_FORMAT_LEFT)
323 Type &= ~ACPI_FORMAT_ZERO;
326 NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE;
327 Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
328 Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' ';
330 /* Calculate size according to sign and prefix */
333 if (Type & ACPI_FORMAT_SIGN)
335 if ((INT64) Number < 0)
338 Number = - (INT64) Number;
341 else if (Type & ACPI_FORMAT_SIGN_PLUS)
346 else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE)
361 /* Generate full string in reverse order */
363 Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper);
364 i = ACPI_PTR_DIFF (Pos, ReversedString);
366 /* Printing 100 using %2d gives "100", not "00" */
375 /* Output the string */
377 if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT)))
381 String = AcpiUtBoundStringOutput (String, End, ' ');
386 String = AcpiUtBoundStringOutput (String, End, Sign);
390 String = AcpiUtBoundStringOutput (String, End, '0');
393 String = AcpiUtBoundStringOutput (String, End,
397 if (!(Type & ACPI_FORMAT_LEFT))
401 String = AcpiUtBoundStringOutput (String, End, Zero);
405 while (i <= --Precision)
407 String = AcpiUtBoundStringOutput (String, End, '0');
411 String = AcpiUtBoundStringOutput (String, End,
416 String = AcpiUtBoundStringOutput (String, End, ' ');
423 /*******************************************************************************
425 * FUNCTION: AcpiUtVsnprintf
427 * PARAMETERS: String - String with boundary
428 * Size - Boundary of the string
429 * Format - Standard printf format
430 * Args - Argument list
432 * RETURN: Number of bytes actually written.
434 * DESCRIPTION: Formatted output to a string using argument list pointer.
436 ******************************************************************************/
463 for (; *Format; ++Format)
467 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
481 Type |= ACPI_FORMAT_PREFIX;
483 else if (*Format == '0')
485 Type |= ACPI_FORMAT_ZERO;
487 else if (*Format == '+')
489 Type |= ACPI_FORMAT_SIGN_PLUS;
491 else if (*Format == ' ')
493 Type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
495 else if (*Format == '-')
497 Type |= ACPI_FORMAT_LEFT;
508 if (isdigit ((int) *Format))
510 Format = AcpiUtScanNumber (Format, &Number);
511 Width = (INT32) Number;
513 else if (*Format == '*')
516 Width = va_arg (Args, int);
520 Type |= ACPI_FORMAT_LEFT;
524 /* Process precision */
530 if (isdigit ((int) *Format))
532 Format = AcpiUtScanNumber (Format, &Number);
533 Precision = (INT32) Number;
535 else if (*Format == '*')
538 Precision = va_arg (Args, int);
546 /* Process qualifier */
549 if (*Format == 'h' || *Format == 'l' || *Format == 'L')
554 if (Qualifier == 'l' && *Format == 'l')
565 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
570 if (!(Type & ACPI_FORMAT_LEFT))
574 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
578 c = (char) va_arg (Args, int);
579 Pos = AcpiUtBoundStringOutput (Pos, End, c);
583 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
589 s = va_arg (Args, char *);
594 Length = AcpiUtBoundStringLength (s, Precision);
595 if (!(Type & ACPI_FORMAT_LEFT))
597 while (Length < Width--)
599 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
602 for (i = 0; i < Length; ++i)
604 Pos = AcpiUtBoundStringOutput (Pos, End, *s);
607 while (Length < Width--)
609 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
620 Type |= ACPI_FORMAT_UPPER;
630 Type |= ACPI_FORMAT_SIGN;
640 Width = 2 * sizeof (void *);
641 Type |= ACPI_FORMAT_ZERO;
644 p = va_arg (Args, void *);
645 Pos = AcpiUtFormatNumber (Pos, End,
646 ACPI_TO_INTEGER (p), 16, Width, Precision, Type);
651 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
654 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
663 if (Qualifier == 'L')
665 Number = va_arg (Args, UINT64);
666 if (Type & ACPI_FORMAT_SIGN)
668 Number = (INT64) Number;
671 else if (Qualifier == 'l')
673 Number = va_arg (Args, unsigned long);
674 if (Type & ACPI_FORMAT_SIGN)
676 Number = (INT32) Number;
679 else if (Qualifier == 'h')
681 Number = (UINT16) va_arg (Args, int);
682 if (Type & ACPI_FORMAT_SIGN)
684 Number = (INT16) Number;
689 Number = va_arg (Args, unsigned int);
690 if (Type & ACPI_FORMAT_SIGN)
692 Number = (signed int) Number;
696 Pos = AcpiUtFormatNumber (Pos, End, Number, Base,
697 Width, Precision, Type);
712 return (ACPI_PTR_DIFF (Pos, String));
716 /*******************************************************************************
718 * FUNCTION: AcpiUtSnprintf
720 * PARAMETERS: String - String with boundary
721 * Size - Boundary of the string
722 * Format, ... - Standard printf format
724 * RETURN: Number of bytes actually written.
726 * DESCRIPTION: Formatted output to a string.
728 ******************************************************************************/
741 va_start (Args, Format);
742 Length = AcpiUtVsnprintf (String, Size, Format, Args);
749 #ifdef ACPI_APPLICATION
750 /*******************************************************************************
752 * FUNCTION: AcpiUtFileVprintf
754 * PARAMETERS: File - File descriptor
755 * Format - Standard printf format
756 * Args - Argument list
758 * RETURN: Number of bytes actually written.
760 * DESCRIPTION: Formatted output to a file using argument list pointer.
762 ******************************************************************************/
770 ACPI_CPU_FLAGS Flags;
774 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
775 Length = AcpiUtVsnprintf (AcpiGbl_PrintBuffer,
776 sizeof (AcpiGbl_PrintBuffer), Format, Args);
778 (void) AcpiOsWriteFile (File, AcpiGbl_PrintBuffer, Length, 1);
779 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
785 /*******************************************************************************
787 * FUNCTION: AcpiUtFilePrintf
789 * PARAMETERS: File - File descriptor
790 * Format, ... - Standard printf format
792 * RETURN: Number of bytes actually written.
794 * DESCRIPTION: Formatted output to a file.
796 ******************************************************************************/
808 va_start (Args, Format);
809 Length = AcpiUtFileVprintf (File, Format, Args);