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.
44 #include <acpi/acpi.h>
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME("utprint")
50 #define ACPI_FORMAT_SIGN 0x01
51 #define ACPI_FORMAT_SIGN_PLUS 0x02
52 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
53 #define ACPI_FORMAT_ZERO 0x08
54 #define ACPI_FORMAT_LEFT 0x10
55 #define ACPI_FORMAT_UPPER 0x20
56 #define ACPI_FORMAT_PREFIX 0x40
57 /* Local prototypes */
59 acpi_ut_bound_string_length(const char *string
, acpi_size count
);
61 static char *acpi_ut_bound_string_output(char *string
, const char *end
, char c
);
63 static char *acpi_ut_format_number(char *string
,
66 u8 base
, s32 width
, s32 precision
, u8 type
);
68 static char *acpi_ut_put_number(char *string
, u64 number
, u8 base
, u8 upper
);
70 /*******************************************************************************
72 * FUNCTION: acpi_ut_bound_string_length
74 * PARAMETERS: string - String with boundary
75 * count - Boundary of the string
77 * RETURN: Length of the string. Less than or equal to Count.
79 * DESCRIPTION: Calculate the length of a string with boundary.
81 ******************************************************************************/
84 acpi_ut_bound_string_length(const char *string
, acpi_size count
)
88 while (*string
&& count
) {
97 /*******************************************************************************
99 * FUNCTION: acpi_ut_bound_string_output
101 * PARAMETERS: string - String with boundary
102 * end - Boundary of the string
103 * c - Character to be output to the string
105 * RETURN: Updated position for next valid character
107 * DESCRIPTION: Output a character into a string with boundary check.
109 ******************************************************************************/
111 static char *acpi_ut_bound_string_output(char *string
, const char *end
, char c
)
122 /*******************************************************************************
124 * FUNCTION: acpi_ut_put_number
126 * PARAMETERS: string - Buffer to hold reverse-ordered string
127 * number - Integer to be converted
128 * base - Base of the integer
129 * upper - Whether or not using upper cased digits
131 * RETURN: Updated position for next valid character
133 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
134 * reversed ordered number without the trailing zero.
136 ******************************************************************************/
138 static char *acpi_ut_put_number(char *string
, u64 number
, u8 base
, u8 upper
)
145 digits
= upper
? acpi_gbl_upper_hex_digits
: acpi_gbl_lower_hex_digits
;
151 (void)acpi_ut_divide(number
, base
, &number
,
153 *(pos
++) = digits
[digit_index
];
157 /* *(Pos++) = '0'; */
161 /*******************************************************************************
163 * FUNCTION: acpi_ut_scan_number
165 * PARAMETERS: string - String buffer
166 * number_ptr - Where the number is returned
168 * RETURN: Updated position for next valid character
170 * DESCRIPTION: Scan a string for a decimal integer.
172 ******************************************************************************/
174 const char *acpi_ut_scan_number(const char *string
, u64
*number_ptr
)
178 while (isdigit((int)*string
)) {
180 number
+= *(string
++) - '0';
183 *number_ptr
= number
;
187 /*******************************************************************************
189 * FUNCTION: acpi_ut_print_number
191 * PARAMETERS: string - String buffer
192 * number - The number to be converted
194 * RETURN: Updated position for next valid character
196 * DESCRIPTION: Print a decimal integer into a string.
198 ******************************************************************************/
200 const char *acpi_ut_print_number(char *string
, u64 number
)
202 char ascii_string
[20];
206 pos1
= acpi_ut_put_number(ascii_string
, number
, 10, FALSE
);
209 while (pos1
!= ascii_string
) {
210 *(pos2
++) = *(--pos1
);
217 /*******************************************************************************
219 * FUNCTION: acpi_ut_format_number
221 * PARAMETERS: string - String buffer with boundary
222 * end - Boundary of the string
223 * number - The number to be converted
224 * base - Base of the integer
225 * width - Field width
226 * precision - Precision of the integer
227 * type - Special printing flags
229 * RETURN: Updated position for next valid character
231 * DESCRIPTION: Print an integer into a string with any base and any precision.
233 ******************************************************************************/
235 static char *acpi_ut_format_number(char *string
,
238 u8 base
, s32 width
, s32 precision
, u8 type
)
246 char reversed_string
[66];
248 /* Parameter validation */
250 if (base
< 2 || base
> 16) {
254 if (type
& ACPI_FORMAT_LEFT
) {
255 type
&= ~ACPI_FORMAT_ZERO
;
258 need_prefix
= ((type
& ACPI_FORMAT_PREFIX
)
259 && base
!= 10) ? TRUE
: FALSE
;
260 upper
= (type
& ACPI_FORMAT_UPPER
) ? TRUE
: FALSE
;
261 zero
= (type
& ACPI_FORMAT_ZERO
) ? '0' : ' ';
263 /* Calculate size according to sign and prefix */
266 if (type
& ACPI_FORMAT_SIGN
) {
267 if ((s64
)number
< 0) {
269 number
= -(s64
)number
;
271 } else if (type
& ACPI_FORMAT_SIGN_PLUS
) {
274 } else if (type
& ACPI_FORMAT_SIGN_PLUS_SPACE
) {
286 /* Generate full string in reverse order */
288 pos
= acpi_ut_put_number(reversed_string
, number
, base
, upper
);
289 i
= ACPI_PTR_DIFF(pos
, reversed_string
);
291 /* Printing 100 using %2d gives "100", not "00" */
299 /* Output the string */
301 if (!(type
& (ACPI_FORMAT_ZERO
| ACPI_FORMAT_LEFT
))) {
302 while (--width
>= 0) {
303 string
= acpi_ut_bound_string_output(string
, end
, ' ');
307 string
= acpi_ut_bound_string_output(string
, end
, sign
);
310 string
= acpi_ut_bound_string_output(string
, end
, '0');
313 acpi_ut_bound_string_output(string
, end
,
317 if (!(type
& ACPI_FORMAT_LEFT
)) {
318 while (--width
>= 0) {
319 string
= acpi_ut_bound_string_output(string
, end
, zero
);
323 while (i
<= --precision
) {
324 string
= acpi_ut_bound_string_output(string
, end
, '0');
327 string
= acpi_ut_bound_string_output(string
, end
,
330 while (--width
>= 0) {
331 string
= acpi_ut_bound_string_output(string
, end
, ' ');
337 /*******************************************************************************
339 * FUNCTION: vsnprintf
341 * PARAMETERS: string - String with boundary
342 * size - Boundary of the string
343 * format - Standard printf format
344 * args - Argument list
346 * RETURN: Number of bytes actually written.
348 * DESCRIPTION: Formatted output to a string using argument list pointer.
350 ******************************************************************************/
352 int vsnprintf(char *string
, acpi_size size
, const char *format
, va_list args
)
371 for (; *format
; ++format
) {
372 if (*format
!= '%') {
373 pos
= acpi_ut_bound_string_output(pos
, end
, *format
);
384 if (*format
== '#') {
385 type
|= ACPI_FORMAT_PREFIX
;
386 } else if (*format
== '0') {
387 type
|= ACPI_FORMAT_ZERO
;
388 } else if (*format
== '+') {
389 type
|= ACPI_FORMAT_SIGN_PLUS
;
390 } else if (*format
== ' ') {
391 type
|= ACPI_FORMAT_SIGN_PLUS_SPACE
;
392 } else if (*format
== '-') {
393 type
|= ACPI_FORMAT_LEFT
;
403 if (isdigit((int)*format
)) {
404 format
= acpi_ut_scan_number(format
, &number
);
406 } else if (*format
== '*') {
408 width
= va_arg(args
, int);
411 type
|= ACPI_FORMAT_LEFT
;
415 /* Process precision */
418 if (*format
== '.') {
420 if (isdigit((int)*format
)) {
421 format
= acpi_ut_scan_number(format
, &number
);
422 precision
= (s32
)number
;
423 } else if (*format
== '*') {
425 precision
= va_arg(args
, int);
433 /* Process qualifier */
436 if (*format
== 'h' || *format
== 'l' || *format
== 'L') {
440 if (qualifier
== 'l' && *format
== 'l') {
449 pos
= acpi_ut_bound_string_output(pos
, end
, '%');
454 if (!(type
& ACPI_FORMAT_LEFT
)) {
455 while (--width
> 0) {
457 acpi_ut_bound_string_output(pos
,
463 c
= (char)va_arg(args
, int);
464 pos
= acpi_ut_bound_string_output(pos
, end
, c
);
466 while (--width
> 0) {
468 acpi_ut_bound_string_output(pos
, end
, ' ');
474 s
= va_arg(args
, char *);
478 length
= acpi_ut_bound_string_length(s
, precision
);
479 if (!(type
& ACPI_FORMAT_LEFT
)) {
480 while (length
< width
--) {
482 acpi_ut_bound_string_output(pos
,
488 for (i
= 0; i
< length
; ++i
) {
489 pos
= acpi_ut_bound_string_output(pos
, end
, *s
);
493 while (length
< width
--) {
495 acpi_ut_bound_string_output(pos
, end
, ' ');
506 type
|= ACPI_FORMAT_UPPER
;
516 type
|= ACPI_FORMAT_SIGN
;
525 width
= 2 * sizeof(void *);
526 type
|= ACPI_FORMAT_ZERO
;
529 p
= va_arg(args
, void *);
531 acpi_ut_format_number(pos
, end
, ACPI_TO_INTEGER(p
),
532 16, width
, precision
, type
);
537 pos
= acpi_ut_bound_string_output(pos
, end
, '%');
540 acpi_ut_bound_string_output(pos
, end
,
548 if (qualifier
== 'L') {
549 number
= va_arg(args
, u64
);
550 if (type
& ACPI_FORMAT_SIGN
) {
551 number
= (s64
)number
;
553 } else if (qualifier
== 'l') {
554 number
= va_arg(args
, unsigned long);
555 if (type
& ACPI_FORMAT_SIGN
) {
556 number
= (s32
)number
;
558 } else if (qualifier
== 'h') {
559 number
= (u16
)va_arg(args
, int);
560 if (type
& ACPI_FORMAT_SIGN
) {
561 number
= (s16
)number
;
564 number
= va_arg(args
, unsigned int);
565 if (type
& ACPI_FORMAT_SIGN
) {
566 number
= (signed int)number
;
570 pos
= acpi_ut_format_number(pos
, end
, number
, base
,
571 width
, precision
, type
);
582 return (ACPI_PTR_DIFF(pos
, string
));
585 /*******************************************************************************
589 * PARAMETERS: string - String with boundary
590 * size - Boundary of the string
591 * Format, ... - Standard printf format
593 * RETURN: Number of bytes actually written.
595 * DESCRIPTION: Formatted output to a string.
597 ******************************************************************************/
599 int snprintf(char *string
, acpi_size size
, const char *format
, ...)
604 va_start(args
, format
);
605 length
= vsnprintf(string
, size
, format
, args
);
611 /*******************************************************************************
615 * PARAMETERS: string - String with boundary
616 * Format, ... - Standard printf format
618 * RETURN: Number of bytes actually written.
620 * DESCRIPTION: Formatted output to a string.
622 ******************************************************************************/
624 int sprintf(char *string
, const char *format
, ...)
629 va_start(args
, format
);
630 length
= vsnprintf(string
, ACPI_UINT32_MAX
, format
, args
);
636 #ifdef ACPI_APPLICATION
637 /*******************************************************************************
641 * PARAMETERS: format - Standard printf format
642 * args - Argument list
644 * RETURN: Number of bytes actually written.
646 * DESCRIPTION: Formatted output to stdout using argument list pointer.
648 ******************************************************************************/
650 int vprintf(const char *format
, va_list args
)
652 acpi_cpu_flags flags
;
655 flags
= acpi_os_acquire_lock(acpi_gbl_print_lock
);
656 length
= vsnprintf(acpi_gbl_print_buffer
,
657 sizeof(acpi_gbl_print_buffer
), format
, args
);
659 (void)fwrite(acpi_gbl_print_buffer
, length
, 1, ACPI_FILE_OUT
);
660 acpi_os_release_lock(acpi_gbl_print_lock
, flags
);
665 /*******************************************************************************
669 * PARAMETERS: Format, ... - Standard printf format
671 * RETURN: Number of bytes actually written.
673 * DESCRIPTION: Formatted output to stdout.
675 ******************************************************************************/
677 int printf(const char *format
, ...)
682 va_start(args
, format
);
683 length
= vprintf(format
, args
);
689 /*******************************************************************************
693 * PARAMETERS: file - File descriptor
694 * format - Standard printf format
695 * args - Argument list
697 * RETURN: Number of bytes actually written.
699 * DESCRIPTION: Formatted output to a file using argument list pointer.
701 ******************************************************************************/
703 int vfprintf(FILE * file
, const char *format
, va_list args
)
705 acpi_cpu_flags flags
;
708 flags
= acpi_os_acquire_lock(acpi_gbl_print_lock
);
709 length
= vsnprintf(acpi_gbl_print_buffer
,
710 sizeof(acpi_gbl_print_buffer
), format
, args
);
712 (void)fwrite(acpi_gbl_print_buffer
, length
, 1, file
);
713 acpi_os_release_lock(acpi_gbl_print_lock
, flags
);
718 /*******************************************************************************
722 * PARAMETERS: file - File descriptor
723 * Format, ... - Standard printf format
725 * RETURN: Number of bytes actually written.
727 * DESCRIPTION: Formatted output to a file.
729 ******************************************************************************/
731 int fprintf(FILE * file
, const char *format
, ...)
736 va_start(args
, format
);
737 length
= vfprintf(file
, format
, args
);