xref: /openbmc/linux/drivers/acpi/acpica/utprint.c (revision 612c2932)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
280a648c1SLv Zheng /******************************************************************************
380a648c1SLv Zheng  *
480a648c1SLv Zheng  * Module Name: utprint - Formatted printing routines
580a648c1SLv Zheng  *
6*612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
780a648c1SLv Zheng  *
895857638SErik Schmauss  *****************************************************************************/
980a648c1SLv Zheng 
1080a648c1SLv Zheng #include <acpi/acpi.h>
1180a648c1SLv Zheng #include "accommon.h"
1280a648c1SLv Zheng 
1380a648c1SLv Zheng #define _COMPONENT          ACPI_UTILITIES
1480a648c1SLv Zheng ACPI_MODULE_NAME("utprint")
1580a648c1SLv Zheng 
1680a648c1SLv Zheng #define ACPI_FORMAT_SIGN            0x01
1780a648c1SLv Zheng #define ACPI_FORMAT_SIGN_PLUS       0x02
1880a648c1SLv Zheng #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
1980a648c1SLv Zheng #define ACPI_FORMAT_ZERO            0x08
2080a648c1SLv Zheng #define ACPI_FORMAT_LEFT            0x10
2180a648c1SLv Zheng #define ACPI_FORMAT_UPPER           0x20
2280a648c1SLv Zheng #define ACPI_FORMAT_PREFIX          0x40
2380a648c1SLv Zheng /* Local prototypes */
2480a648c1SLv Zheng static acpi_size
2580a648c1SLv Zheng acpi_ut_bound_string_length(const char *string, acpi_size count);
2680a648c1SLv Zheng 
2780a648c1SLv Zheng static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
2880a648c1SLv Zheng 
2980a648c1SLv Zheng static char *acpi_ut_format_number(char *string,
3080a648c1SLv Zheng 				   char *end,
3180a648c1SLv Zheng 				   u64 number,
3280a648c1SLv Zheng 				   u8 base, s32 width, s32 precision, u8 type);
3380a648c1SLv Zheng 
3480a648c1SLv Zheng static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
3580a648c1SLv Zheng 
3680a648c1SLv Zheng /*******************************************************************************
3780a648c1SLv Zheng  *
3880a648c1SLv Zheng  * FUNCTION:    acpi_ut_bound_string_length
3980a648c1SLv Zheng  *
4080a648c1SLv Zheng  * PARAMETERS:  string              - String with boundary
4180a648c1SLv Zheng  *              count               - Boundary of the string
4280a648c1SLv Zheng  *
43ff2389feSBob Moore  * RETURN:      Length of the string. Less than or equal to Count.
4480a648c1SLv Zheng  *
4580a648c1SLv Zheng  * DESCRIPTION: Calculate the length of a string with boundary.
4680a648c1SLv Zheng  *
4780a648c1SLv Zheng  ******************************************************************************/
4880a648c1SLv Zheng 
4980a648c1SLv Zheng static acpi_size
acpi_ut_bound_string_length(const char * string,acpi_size count)5080a648c1SLv Zheng acpi_ut_bound_string_length(const char *string, acpi_size count)
5180a648c1SLv Zheng {
5280a648c1SLv Zheng 	u32 length = 0;
5380a648c1SLv Zheng 
5480a648c1SLv Zheng 	while (*string && count) {
5580a648c1SLv Zheng 		length++;
5680a648c1SLv Zheng 		string++;
5780a648c1SLv Zheng 		count--;
5880a648c1SLv Zheng 	}
5980a648c1SLv Zheng 
6080a648c1SLv Zheng 	return (length);
6180a648c1SLv Zheng }
6280a648c1SLv Zheng 
6380a648c1SLv Zheng /*******************************************************************************
6480a648c1SLv Zheng  *
6580a648c1SLv Zheng  * FUNCTION:    acpi_ut_bound_string_output
6680a648c1SLv Zheng  *
6780a648c1SLv Zheng  * PARAMETERS:  string              - String with boundary
6880a648c1SLv Zheng  *              end                 - Boundary of the string
6980a648c1SLv Zheng  *              c                   - Character to be output to the string
7080a648c1SLv Zheng  *
7180a648c1SLv Zheng  * RETURN:      Updated position for next valid character
7280a648c1SLv Zheng  *
7380a648c1SLv Zheng  * DESCRIPTION: Output a character into a string with boundary check.
7480a648c1SLv Zheng  *
7580a648c1SLv Zheng  ******************************************************************************/
7680a648c1SLv Zheng 
acpi_ut_bound_string_output(char * string,const char * end,char c)7780a648c1SLv Zheng static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
7880a648c1SLv Zheng {
7980a648c1SLv Zheng 
8080a648c1SLv Zheng 	if (string < end) {
8180a648c1SLv Zheng 		*string = c;
8280a648c1SLv Zheng 	}
8380a648c1SLv Zheng 
84ff2389feSBob Moore 	++string;
8580a648c1SLv Zheng 	return (string);
8680a648c1SLv Zheng }
8780a648c1SLv Zheng 
8880a648c1SLv Zheng /*******************************************************************************
8980a648c1SLv Zheng  *
9080a648c1SLv Zheng  * FUNCTION:    acpi_ut_put_number
9180a648c1SLv Zheng  *
9280a648c1SLv Zheng  * PARAMETERS:  string              - Buffer to hold reverse-ordered string
9380a648c1SLv Zheng  *              number              - Integer to be converted
9480a648c1SLv Zheng  *              base                - Base of the integer
9580a648c1SLv Zheng  *              upper               - Whether or not using upper cased digits
9680a648c1SLv Zheng  *
9780a648c1SLv Zheng  * RETURN:      Updated position for next valid character
9880a648c1SLv Zheng  *
9980a648c1SLv Zheng  * DESCRIPTION: Convert an integer into a string, note that, the string holds a
10080a648c1SLv Zheng  *              reversed ordered number without the trailing zero.
10180a648c1SLv Zheng  *
10280a648c1SLv Zheng  ******************************************************************************/
10380a648c1SLv Zheng 
acpi_ut_put_number(char * string,u64 number,u8 base,u8 upper)10480a648c1SLv Zheng static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
10580a648c1SLv Zheng {
10680a648c1SLv Zheng 	const char *digits;
10780a648c1SLv Zheng 	u64 digit_index;
10880a648c1SLv Zheng 	char *pos;
10980a648c1SLv Zheng 
11080a648c1SLv Zheng 	pos = string;
111ff2389feSBob Moore 	digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
11280a648c1SLv Zheng 
11380a648c1SLv Zheng 	if (number == 0) {
11480a648c1SLv Zheng 		*(pos++) = '0';
11580a648c1SLv Zheng 	} else {
11680a648c1SLv Zheng 		while (number) {
11780a648c1SLv Zheng 			(void)acpi_ut_divide(number, base, &number,
11880a648c1SLv Zheng 					     &digit_index);
11980a648c1SLv Zheng 			*(pos++) = digits[digit_index];
12080a648c1SLv Zheng 		}
12180a648c1SLv Zheng 	}
12280a648c1SLv Zheng 
123ff2389feSBob Moore 	/* *(Pos++) = '0'; */
12480a648c1SLv Zheng 	return (pos);
12580a648c1SLv Zheng }
12680a648c1SLv Zheng 
12780a648c1SLv Zheng /*******************************************************************************
12880a648c1SLv Zheng  *
12980a648c1SLv Zheng  * FUNCTION:    acpi_ut_scan_number
13080a648c1SLv Zheng  *
13180a648c1SLv Zheng  * PARAMETERS:  string              - String buffer
13280a648c1SLv Zheng  *              number_ptr          - Where the number is returned
13380a648c1SLv Zheng  *
13480a648c1SLv Zheng  * RETURN:      Updated position for next valid character
13580a648c1SLv Zheng  *
13680a648c1SLv Zheng  * DESCRIPTION: Scan a string for a decimal integer.
13780a648c1SLv Zheng  *
13880a648c1SLv Zheng  ******************************************************************************/
13980a648c1SLv Zheng 
acpi_ut_scan_number(const char * string,u64 * number_ptr)14080a648c1SLv Zheng const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
14180a648c1SLv Zheng {
14280a648c1SLv Zheng 	u64 number = 0;
14380a648c1SLv Zheng 
1444fa4616eSBob Moore 	while (isdigit((int)*string)) {
14565082bfcSLv Zheng 		acpi_ut_short_multiply(number, 10, &number);
14680a648c1SLv Zheng 		number += *(string++) - '0';
14780a648c1SLv Zheng 	}
14880a648c1SLv Zheng 
149ff2389feSBob Moore 	*number_ptr = number;
15080a648c1SLv Zheng 	return (string);
15180a648c1SLv Zheng }
15280a648c1SLv Zheng 
15380a648c1SLv Zheng /*******************************************************************************
15480a648c1SLv Zheng  *
15580a648c1SLv Zheng  * FUNCTION:    acpi_ut_print_number
15680a648c1SLv Zheng  *
15780a648c1SLv Zheng  * PARAMETERS:  string              - String buffer
15880a648c1SLv Zheng  *              number              - The number to be converted
15980a648c1SLv Zheng  *
16080a648c1SLv Zheng  * RETURN:      Updated position for next valid character
16180a648c1SLv Zheng  *
16280a648c1SLv Zheng  * DESCRIPTION: Print a decimal integer into a string.
16380a648c1SLv Zheng  *
16480a648c1SLv Zheng  ******************************************************************************/
16580a648c1SLv Zheng 
acpi_ut_print_number(char * string,u64 number)16680a648c1SLv Zheng const char *acpi_ut_print_number(char *string, u64 number)
16780a648c1SLv Zheng {
16880a648c1SLv Zheng 	char ascii_string[20];
16980a648c1SLv Zheng 	const char *pos1;
17080a648c1SLv Zheng 	char *pos2;
17180a648c1SLv Zheng 
17280a648c1SLv Zheng 	pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
17380a648c1SLv Zheng 	pos2 = string;
17480a648c1SLv Zheng 
17580a648c1SLv Zheng 	while (pos1 != ascii_string) {
17680a648c1SLv Zheng 		*(pos2++) = *(--pos1);
17780a648c1SLv Zheng 	}
17880a648c1SLv Zheng 
179ff2389feSBob Moore 	*pos2 = 0;
18080a648c1SLv Zheng 	return (string);
18180a648c1SLv Zheng }
18280a648c1SLv Zheng 
18380a648c1SLv Zheng /*******************************************************************************
18480a648c1SLv Zheng  *
18580a648c1SLv Zheng  * FUNCTION:    acpi_ut_format_number
18680a648c1SLv Zheng  *
18780a648c1SLv Zheng  * PARAMETERS:  string              - String buffer with boundary
18880a648c1SLv Zheng  *              end                 - Boundary of the string
18980a648c1SLv Zheng  *              number              - The number to be converted
19080a648c1SLv Zheng  *              base                - Base of the integer
19180a648c1SLv Zheng  *              width               - Field width
19280a648c1SLv Zheng  *              precision           - Precision of the integer
19380a648c1SLv Zheng  *              type                - Special printing flags
19480a648c1SLv Zheng  *
19580a648c1SLv Zheng  * RETURN:      Updated position for next valid character
19680a648c1SLv Zheng  *
19780a648c1SLv Zheng  * DESCRIPTION: Print an integer into a string with any base and any precision.
19880a648c1SLv Zheng  *
19980a648c1SLv Zheng  ******************************************************************************/
20080a648c1SLv Zheng 
acpi_ut_format_number(char * string,char * end,u64 number,u8 base,s32 width,s32 precision,u8 type)20180a648c1SLv Zheng static char *acpi_ut_format_number(char *string,
20280a648c1SLv Zheng 				   char *end,
20380a648c1SLv Zheng 				   u64 number,
20480a648c1SLv Zheng 				   u8 base, s32 width, s32 precision, u8 type)
20580a648c1SLv Zheng {
2068884de6aSBob Moore 	char *pos;
20780a648c1SLv Zheng 	char sign;
20880a648c1SLv Zheng 	char zero;
20980a648c1SLv Zheng 	u8 need_prefix;
21080a648c1SLv Zheng 	u8 upper;
21180a648c1SLv Zheng 	s32 i;
21280a648c1SLv Zheng 	char reversed_string[66];
21380a648c1SLv Zheng 
214ff2389feSBob Moore 	/* Parameter validation */
21580a648c1SLv Zheng 
21680a648c1SLv Zheng 	if (base < 2 || base > 16) {
217ff2389feSBob Moore 		return (NULL);
21880a648c1SLv Zheng 	}
219ff2389feSBob Moore 
22080a648c1SLv Zheng 	if (type & ACPI_FORMAT_LEFT) {
22180a648c1SLv Zheng 		type &= ~ACPI_FORMAT_ZERO;
22280a648c1SLv Zheng 	}
22380a648c1SLv Zheng 
22480a648c1SLv Zheng 	need_prefix = ((type & ACPI_FORMAT_PREFIX)
22580a648c1SLv Zheng 		       && base != 10) ? TRUE : FALSE;
22680a648c1SLv Zheng 	upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
22780a648c1SLv Zheng 	zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
22880a648c1SLv Zheng 
22980a648c1SLv Zheng 	/* Calculate size according to sign and prefix */
23080a648c1SLv Zheng 
23180a648c1SLv Zheng 	sign = '\0';
23280a648c1SLv Zheng 	if (type & ACPI_FORMAT_SIGN) {
23380a648c1SLv Zheng 		if ((s64)number < 0) {
23480a648c1SLv Zheng 			sign = '-';
23580a648c1SLv Zheng 			number = -(s64)number;
23680a648c1SLv Zheng 			width--;
23780a648c1SLv Zheng 		} else if (type & ACPI_FORMAT_SIGN_PLUS) {
23880a648c1SLv Zheng 			sign = '+';
23980a648c1SLv Zheng 			width--;
24080a648c1SLv Zheng 		} else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
24180a648c1SLv Zheng 			sign = ' ';
24280a648c1SLv Zheng 			width--;
24380a648c1SLv Zheng 		}
24480a648c1SLv Zheng 	}
24580a648c1SLv Zheng 	if (need_prefix) {
24680a648c1SLv Zheng 		width--;
24780a648c1SLv Zheng 		if (base == 16) {
24880a648c1SLv Zheng 			width--;
24980a648c1SLv Zheng 		}
25080a648c1SLv Zheng 	}
25180a648c1SLv Zheng 
25280a648c1SLv Zheng 	/* Generate full string in reverse order */
25380a648c1SLv Zheng 
2548884de6aSBob Moore 	pos = acpi_ut_put_number(reversed_string, number, base, upper);
2553958168fSLv Zheng 	i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
25680a648c1SLv Zheng 
25780a648c1SLv Zheng 	/* Printing 100 using %2d gives "100", not "00" */
25880a648c1SLv Zheng 
25980a648c1SLv Zheng 	if (i > precision) {
26080a648c1SLv Zheng 		precision = i;
26180a648c1SLv Zheng 	}
262ff2389feSBob Moore 
26380a648c1SLv Zheng 	width -= precision;
26480a648c1SLv Zheng 
26580a648c1SLv Zheng 	/* Output the string */
26680a648c1SLv Zheng 
26780a648c1SLv Zheng 	if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
26880a648c1SLv Zheng 		while (--width >= 0) {
26980a648c1SLv Zheng 			string = acpi_ut_bound_string_output(string, end, ' ');
27080a648c1SLv Zheng 		}
27180a648c1SLv Zheng 	}
27280a648c1SLv Zheng 	if (sign) {
27380a648c1SLv Zheng 		string = acpi_ut_bound_string_output(string, end, sign);
27480a648c1SLv Zheng 	}
27580a648c1SLv Zheng 	if (need_prefix) {
27680a648c1SLv Zheng 		string = acpi_ut_bound_string_output(string, end, '0');
27780a648c1SLv Zheng 		if (base == 16) {
2781fad8738SBob Moore 			string =
2791fad8738SBob Moore 			    acpi_ut_bound_string_output(string, end,
28080a648c1SLv Zheng 							upper ? 'X' : 'x');
28180a648c1SLv Zheng 		}
28280a648c1SLv Zheng 	}
28380a648c1SLv Zheng 	if (!(type & ACPI_FORMAT_LEFT)) {
28480a648c1SLv Zheng 		while (--width >= 0) {
28580a648c1SLv Zheng 			string = acpi_ut_bound_string_output(string, end, zero);
28680a648c1SLv Zheng 		}
28780a648c1SLv Zheng 	}
288ff2389feSBob Moore 
28980a648c1SLv Zheng 	while (i <= --precision) {
29080a648c1SLv Zheng 		string = acpi_ut_bound_string_output(string, end, '0');
29180a648c1SLv Zheng 	}
29280a648c1SLv Zheng 	while (--i >= 0) {
29380a648c1SLv Zheng 		string = acpi_ut_bound_string_output(string, end,
29480a648c1SLv Zheng 						     reversed_string[i]);
29580a648c1SLv Zheng 	}
29680a648c1SLv Zheng 	while (--width >= 0) {
29780a648c1SLv Zheng 		string = acpi_ut_bound_string_output(string, end, ' ');
29880a648c1SLv Zheng 	}
29980a648c1SLv Zheng 
30080a648c1SLv Zheng 	return (string);
30180a648c1SLv Zheng }
30280a648c1SLv Zheng 
30380a648c1SLv Zheng /*******************************************************************************
30480a648c1SLv Zheng  *
305f173a775SLv Zheng  * FUNCTION:    vsnprintf
30680a648c1SLv Zheng  *
30780a648c1SLv Zheng  * PARAMETERS:  string              - String with boundary
30880a648c1SLv Zheng  *              size                - Boundary of the string
30980a648c1SLv Zheng  *              format              - Standard printf format
31080a648c1SLv Zheng  *              args                - Argument list
31180a648c1SLv Zheng  *
312ff2389feSBob Moore  * RETURN:      Number of bytes actually written.
31380a648c1SLv Zheng  *
31480a648c1SLv Zheng  * DESCRIPTION: Formatted output to a string using argument list pointer.
31580a648c1SLv Zheng  *
31680a648c1SLv Zheng  ******************************************************************************/
31780a648c1SLv Zheng 
vsnprintf(char * string,acpi_size size,const char * format,va_list args)318f173a775SLv Zheng int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
31980a648c1SLv Zheng {
320cef9aaa7SLv Zheng 	u8 base;
321cef9aaa7SLv Zheng 	u8 type;
322cef9aaa7SLv Zheng 	s32 width;
323cef9aaa7SLv Zheng 	s32 precision;
324cef9aaa7SLv Zheng 	char qualifier;
32580a648c1SLv Zheng 	u64 number;
32680a648c1SLv Zheng 	char *pos;
32780a648c1SLv Zheng 	char *end;
32880a648c1SLv Zheng 	char c;
32980a648c1SLv Zheng 	const char *s;
33080a648c1SLv Zheng 	const void *p;
33180a648c1SLv Zheng 	s32 length;
33280a648c1SLv Zheng 	int i;
33380a648c1SLv Zheng 
33480a648c1SLv Zheng 	pos = string;
335bb89a79aSJohn Levon 
336bb89a79aSJohn Levon 	if (size != ACPI_UINT32_MAX) {
33780a648c1SLv Zheng 		end = string + size;
338bb89a79aSJohn Levon 	} else {
339bb89a79aSJohn Levon 		end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
340bb89a79aSJohn Levon 	}
34180a648c1SLv Zheng 
34280a648c1SLv Zheng 	for (; *format; ++format) {
34380a648c1SLv Zheng 		if (*format != '%') {
34480a648c1SLv Zheng 			pos = acpi_ut_bound_string_output(pos, end, *format);
34580a648c1SLv Zheng 			continue;
34680a648c1SLv Zheng 		}
34780a648c1SLv Zheng 
348cef9aaa7SLv Zheng 		type = 0;
349cef9aaa7SLv Zheng 		base = 10;
350cef9aaa7SLv Zheng 
35180a648c1SLv Zheng 		/* Process sign */
35280a648c1SLv Zheng 
35380a648c1SLv Zheng 		do {
35480a648c1SLv Zheng 			++format;
35580a648c1SLv Zheng 			if (*format == '#') {
35680a648c1SLv Zheng 				type |= ACPI_FORMAT_PREFIX;
35780a648c1SLv Zheng 			} else if (*format == '0') {
35880a648c1SLv Zheng 				type |= ACPI_FORMAT_ZERO;
35980a648c1SLv Zheng 			} else if (*format == '+') {
36080a648c1SLv Zheng 				type |= ACPI_FORMAT_SIGN_PLUS;
36180a648c1SLv Zheng 			} else if (*format == ' ') {
36280a648c1SLv Zheng 				type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
36380a648c1SLv Zheng 			} else if (*format == '-') {
36480a648c1SLv Zheng 				type |= ACPI_FORMAT_LEFT;
36580a648c1SLv Zheng 			} else {
36680a648c1SLv Zheng 				break;
36780a648c1SLv Zheng 			}
3681fad8738SBob Moore 
36980a648c1SLv Zheng 		} while (1);
37080a648c1SLv Zheng 
37180a648c1SLv Zheng 		/* Process width */
37280a648c1SLv Zheng 
3733589b8b8SLv Zheng 		width = -1;
3744fa4616eSBob Moore 		if (isdigit((int)*format)) {
37580a648c1SLv Zheng 			format = acpi_ut_scan_number(format, &number);
37680a648c1SLv Zheng 			width = (s32)number;
37780a648c1SLv Zheng 		} else if (*format == '*') {
37880a648c1SLv Zheng 			++format;
37980a648c1SLv Zheng 			width = va_arg(args, int);
38080a648c1SLv Zheng 			if (width < 0) {
38180a648c1SLv Zheng 				width = -width;
38280a648c1SLv Zheng 				type |= ACPI_FORMAT_LEFT;
38380a648c1SLv Zheng 			}
38480a648c1SLv Zheng 		}
38580a648c1SLv Zheng 
38680a648c1SLv Zheng 		/* Process precision */
38780a648c1SLv Zheng 
3883589b8b8SLv Zheng 		precision = -1;
38980a648c1SLv Zheng 		if (*format == '.') {
39080a648c1SLv Zheng 			++format;
3914fa4616eSBob Moore 			if (isdigit((int)*format)) {
39280a648c1SLv Zheng 				format = acpi_ut_scan_number(format, &number);
39380a648c1SLv Zheng 				precision = (s32)number;
39480a648c1SLv Zheng 			} else if (*format == '*') {
39580a648c1SLv Zheng 				++format;
39680a648c1SLv Zheng 				precision = va_arg(args, int);
39780a648c1SLv Zheng 			}
3981fad8738SBob Moore 
39980a648c1SLv Zheng 			if (precision < 0) {
40080a648c1SLv Zheng 				precision = 0;
40180a648c1SLv Zheng 			}
40280a648c1SLv Zheng 		}
40380a648c1SLv Zheng 
40480a648c1SLv Zheng 		/* Process qualifier */
40580a648c1SLv Zheng 
4063589b8b8SLv Zheng 		qualifier = -1;
40780a648c1SLv Zheng 		if (*format == 'h' || *format == 'l' || *format == 'L') {
40880a648c1SLv Zheng 			qualifier = *format;
40980a648c1SLv Zheng 			++format;
410ff2389feSBob Moore 
41180a648c1SLv Zheng 			if (qualifier == 'l' && *format == 'l') {
41280a648c1SLv Zheng 				qualifier = 'L';
41380a648c1SLv Zheng 				++format;
41480a648c1SLv Zheng 			}
41580a648c1SLv Zheng 		}
41680a648c1SLv Zheng 
41780a648c1SLv Zheng 		switch (*format) {
41880a648c1SLv Zheng 		case '%':
41980a648c1SLv Zheng 
42080a648c1SLv Zheng 			pos = acpi_ut_bound_string_output(pos, end, '%');
42180a648c1SLv Zheng 			continue;
42280a648c1SLv Zheng 
42380a648c1SLv Zheng 		case 'c':
42480a648c1SLv Zheng 
42580a648c1SLv Zheng 			if (!(type & ACPI_FORMAT_LEFT)) {
42680a648c1SLv Zheng 				while (--width > 0) {
42780a648c1SLv Zheng 					pos =
42880a648c1SLv Zheng 					    acpi_ut_bound_string_output(pos,
42980a648c1SLv Zheng 									end,
43080a648c1SLv Zheng 									' ');
43180a648c1SLv Zheng 				}
43280a648c1SLv Zheng 			}
433ff2389feSBob Moore 
43480a648c1SLv Zheng 			c = (char)va_arg(args, int);
43580a648c1SLv Zheng 			pos = acpi_ut_bound_string_output(pos, end, c);
436ff2389feSBob Moore 
43780a648c1SLv Zheng 			while (--width > 0) {
43880a648c1SLv Zheng 				pos =
43980a648c1SLv Zheng 				    acpi_ut_bound_string_output(pos, end, ' ');
44080a648c1SLv Zheng 			}
44180a648c1SLv Zheng 			continue;
44280a648c1SLv Zheng 
44380a648c1SLv Zheng 		case 's':
44480a648c1SLv Zheng 
44580a648c1SLv Zheng 			s = va_arg(args, char *);
44680a648c1SLv Zheng 			if (!s) {
44780a648c1SLv Zheng 				s = "<NULL>";
44880a648c1SLv Zheng 			}
4493958168fSLv Zheng 			length = (s32)acpi_ut_bound_string_length(s, precision);
45080a648c1SLv Zheng 			if (!(type & ACPI_FORMAT_LEFT)) {
45180a648c1SLv Zheng 				while (length < width--) {
45280a648c1SLv Zheng 					pos =
45380a648c1SLv Zheng 					    acpi_ut_bound_string_output(pos,
45480a648c1SLv Zheng 									end,
45580a648c1SLv Zheng 									' ');
45680a648c1SLv Zheng 				}
45780a648c1SLv Zheng 			}
4581fad8738SBob Moore 
45980a648c1SLv Zheng 			for (i = 0; i < length; ++i) {
46080a648c1SLv Zheng 				pos = acpi_ut_bound_string_output(pos, end, *s);
46180a648c1SLv Zheng 				++s;
46280a648c1SLv Zheng 			}
4631fad8738SBob Moore 
46480a648c1SLv Zheng 			while (length < width--) {
46580a648c1SLv Zheng 				pos =
46680a648c1SLv Zheng 				    acpi_ut_bound_string_output(pos, end, ' ');
46780a648c1SLv Zheng 			}
46880a648c1SLv Zheng 			continue;
46980a648c1SLv Zheng 
47080a648c1SLv Zheng 		case 'o':
47180a648c1SLv Zheng 
47280a648c1SLv Zheng 			base = 8;
47380a648c1SLv Zheng 			break;
47480a648c1SLv Zheng 
47580a648c1SLv Zheng 		case 'X':
47680a648c1SLv Zheng 
47780a648c1SLv Zheng 			type |= ACPI_FORMAT_UPPER;
478b5e77403SWei Ming Chen 			ACPI_FALLTHROUGH;
47980a648c1SLv Zheng 
48080a648c1SLv Zheng 		case 'x':
48180a648c1SLv Zheng 
48280a648c1SLv Zheng 			base = 16;
48380a648c1SLv Zheng 			break;
48480a648c1SLv Zheng 
48580a648c1SLv Zheng 		case 'd':
48680a648c1SLv Zheng 		case 'i':
48780a648c1SLv Zheng 
48880a648c1SLv Zheng 			type |= ACPI_FORMAT_SIGN;
48980a648c1SLv Zheng 
49080a648c1SLv Zheng 		case 'u':
49180a648c1SLv Zheng 
49280a648c1SLv Zheng 			break;
49380a648c1SLv Zheng 
49480a648c1SLv Zheng 		case 'p':
49580a648c1SLv Zheng 
49680a648c1SLv Zheng 			if (width == -1) {
49780a648c1SLv Zheng 				width = 2 * sizeof(void *);
49880a648c1SLv Zheng 				type |= ACPI_FORMAT_ZERO;
49980a648c1SLv Zheng 			}
500ff2389feSBob Moore 
50180a648c1SLv Zheng 			p = va_arg(args, void *);
5021fad8738SBob Moore 			pos =
5031fad8738SBob Moore 			    acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
5041fad8738SBob Moore 						  16, width, precision, type);
50580a648c1SLv Zheng 			continue;
50680a648c1SLv Zheng 
50780a648c1SLv Zheng 		default:
50880a648c1SLv Zheng 
50980a648c1SLv Zheng 			pos = acpi_ut_bound_string_output(pos, end, '%');
51080a648c1SLv Zheng 			if (*format) {
51180a648c1SLv Zheng 				pos =
51280a648c1SLv Zheng 				    acpi_ut_bound_string_output(pos, end,
51380a648c1SLv Zheng 								*format);
51480a648c1SLv Zheng 			} else {
51580a648c1SLv Zheng 				--format;
51680a648c1SLv Zheng 			}
51780a648c1SLv Zheng 			continue;
51880a648c1SLv Zheng 		}
51980a648c1SLv Zheng 
52080a648c1SLv Zheng 		if (qualifier == 'L') {
52180a648c1SLv Zheng 			number = va_arg(args, u64);
52280a648c1SLv Zheng 			if (type & ACPI_FORMAT_SIGN) {
52380a648c1SLv Zheng 				number = (s64)number;
52480a648c1SLv Zheng 			}
52580a648c1SLv Zheng 		} else if (qualifier == 'l') {
52680a648c1SLv Zheng 			number = va_arg(args, unsigned long);
52780a648c1SLv Zheng 			if (type & ACPI_FORMAT_SIGN) {
52880a648c1SLv Zheng 				number = (s32)number;
52980a648c1SLv Zheng 			}
53080a648c1SLv Zheng 		} else if (qualifier == 'h') {
53180a648c1SLv Zheng 			number = (u16)va_arg(args, int);
53280a648c1SLv Zheng 			if (type & ACPI_FORMAT_SIGN) {
53380a648c1SLv Zheng 				number = (s16)number;
53480a648c1SLv Zheng 			}
53580a648c1SLv Zheng 		} else {
53680a648c1SLv Zheng 			number = va_arg(args, unsigned int);
53780a648c1SLv Zheng 			if (type & ACPI_FORMAT_SIGN) {
53880a648c1SLv Zheng 				number = (signed int)number;
53980a648c1SLv Zheng 			}
54080a648c1SLv Zheng 		}
541ff2389feSBob Moore 
54280a648c1SLv Zheng 		pos = acpi_ut_format_number(pos, end, number, base,
54380a648c1SLv Zheng 					    width, precision, type);
54480a648c1SLv Zheng 	}
54580a648c1SLv Zheng 
54680a648c1SLv Zheng 	if (size > 0) {
54780a648c1SLv Zheng 		if (pos < end) {
54880a648c1SLv Zheng 			*pos = '\0';
54980a648c1SLv Zheng 		} else {
55080a648c1SLv Zheng 			end[-1] = '\0';
55180a648c1SLv Zheng 		}
55280a648c1SLv Zheng 	}
55380a648c1SLv Zheng 
5543958168fSLv Zheng 	return ((int)ACPI_PTR_DIFF(pos, string));
55580a648c1SLv Zheng }
55680a648c1SLv Zheng 
55780a648c1SLv Zheng /*******************************************************************************
55880a648c1SLv Zheng  *
559f173a775SLv Zheng  * FUNCTION:    snprintf
56080a648c1SLv Zheng  *
56180a648c1SLv Zheng  * PARAMETERS:  string              - String with boundary
56280a648c1SLv Zheng  *              size                - Boundary of the string
56380a648c1SLv Zheng  *              Format, ...         - Standard printf format
56480a648c1SLv Zheng  *
565ff2389feSBob Moore  * RETURN:      Number of bytes actually written.
56680a648c1SLv Zheng  *
56780a648c1SLv Zheng  * DESCRIPTION: Formatted output to a string.
56880a648c1SLv Zheng  *
56980a648c1SLv Zheng  ******************************************************************************/
57080a648c1SLv Zheng 
snprintf(char * string,acpi_size size,const char * format,...)571f173a775SLv Zheng int snprintf(char *string, acpi_size size, const char *format, ...)
57280a648c1SLv Zheng {
57380a648c1SLv Zheng 	va_list args;
57480a648c1SLv Zheng 	int length;
57580a648c1SLv Zheng 
57680a648c1SLv Zheng 	va_start(args, format);
577f173a775SLv Zheng 	length = vsnprintf(string, size, format, args);
578f173a775SLv Zheng 	va_end(args);
579f173a775SLv Zheng 
580f173a775SLv Zheng 	return (length);
581f173a775SLv Zheng }
582f173a775SLv Zheng 
583f173a775SLv Zheng /*******************************************************************************
584f173a775SLv Zheng  *
585f173a775SLv Zheng  * FUNCTION:    sprintf
586f173a775SLv Zheng  *
587f173a775SLv Zheng  * PARAMETERS:  string              - String with boundary
588f173a775SLv Zheng  *              Format, ...         - Standard printf format
589f173a775SLv Zheng  *
590f173a775SLv Zheng  * RETURN:      Number of bytes actually written.
591f173a775SLv Zheng  *
592f173a775SLv Zheng  * DESCRIPTION: Formatted output to a string.
593f173a775SLv Zheng  *
594f173a775SLv Zheng  ******************************************************************************/
595f173a775SLv Zheng 
sprintf(char * string,const char * format,...)596f173a775SLv Zheng int sprintf(char *string, const char *format, ...)
597f173a775SLv Zheng {
598f173a775SLv Zheng 	va_list args;
599f173a775SLv Zheng 	int length;
600f173a775SLv Zheng 
601f173a775SLv Zheng 	va_start(args, format);
602f173a775SLv Zheng 	length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
60380a648c1SLv Zheng 	va_end(args);
60480a648c1SLv Zheng 
60580a648c1SLv Zheng 	return (length);
60680a648c1SLv Zheng }
60780a648c1SLv Zheng 
60880a648c1SLv Zheng #ifdef ACPI_APPLICATION
60980a648c1SLv Zheng /*******************************************************************************
61080a648c1SLv Zheng  *
611f173a775SLv Zheng  * FUNCTION:    vprintf
612f173a775SLv Zheng  *
613f173a775SLv Zheng  * PARAMETERS:  format              - Standard printf format
614f173a775SLv Zheng  *              args                - Argument list
615f173a775SLv Zheng  *
616f173a775SLv Zheng  * RETURN:      Number of bytes actually written.
617f173a775SLv Zheng  *
618f173a775SLv Zheng  * DESCRIPTION: Formatted output to stdout using argument list pointer.
619f173a775SLv Zheng  *
620f173a775SLv Zheng  ******************************************************************************/
621f173a775SLv Zheng 
vprintf(const char * format,va_list args)622f173a775SLv Zheng int vprintf(const char *format, va_list args)
623f173a775SLv Zheng {
624f173a775SLv Zheng 	acpi_cpu_flags flags;
625f173a775SLv Zheng 	int length;
626f173a775SLv Zheng 
627f173a775SLv Zheng 	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
628f173a775SLv Zheng 	length = vsnprintf(acpi_gbl_print_buffer,
629f173a775SLv Zheng 			   sizeof(acpi_gbl_print_buffer), format, args);
630f173a775SLv Zheng 
631dd99cbccSLv Zheng 	(void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
632f173a775SLv Zheng 	acpi_os_release_lock(acpi_gbl_print_lock, flags);
633f173a775SLv Zheng 
634f173a775SLv Zheng 	return (length);
635f173a775SLv Zheng }
636f173a775SLv Zheng 
637f173a775SLv Zheng /*******************************************************************************
638f173a775SLv Zheng  *
639f173a775SLv Zheng  * FUNCTION:    printf
640f173a775SLv Zheng  *
641f173a775SLv Zheng  * PARAMETERS:  Format, ...         - Standard printf format
642f173a775SLv Zheng  *
643f173a775SLv Zheng  * RETURN:      Number of bytes actually written.
644f173a775SLv Zheng  *
645f173a775SLv Zheng  * DESCRIPTION: Formatted output to stdout.
646f173a775SLv Zheng  *
647f173a775SLv Zheng  ******************************************************************************/
648f173a775SLv Zheng 
printf(const char * format,...)649f173a775SLv Zheng int printf(const char *format, ...)
650f173a775SLv Zheng {
651f173a775SLv Zheng 	va_list args;
652f173a775SLv Zheng 	int length;
653f173a775SLv Zheng 
654f173a775SLv Zheng 	va_start(args, format);
655f173a775SLv Zheng 	length = vprintf(format, args);
656f173a775SLv Zheng 	va_end(args);
657f173a775SLv Zheng 
658f173a775SLv Zheng 	return (length);
659f173a775SLv Zheng }
660f173a775SLv Zheng 
661f173a775SLv Zheng /*******************************************************************************
662f173a775SLv Zheng  *
663f173a775SLv Zheng  * FUNCTION:    vfprintf
66480a648c1SLv Zheng  *
66580a648c1SLv Zheng  * PARAMETERS:  file                - File descriptor
66680a648c1SLv Zheng  *              format              - Standard printf format
66780a648c1SLv Zheng  *              args                - Argument list
66880a648c1SLv Zheng  *
669ff2389feSBob Moore  * RETURN:      Number of bytes actually written.
67080a648c1SLv Zheng  *
67180a648c1SLv Zheng  * DESCRIPTION: Formatted output to a file using argument list pointer.
67280a648c1SLv Zheng  *
67380a648c1SLv Zheng  ******************************************************************************/
67480a648c1SLv Zheng 
vfprintf(FILE * file,const char * format,va_list args)675f173a775SLv Zheng int vfprintf(FILE * file, const char *format, va_list args)
67680a648c1SLv Zheng {
67780a648c1SLv Zheng 	acpi_cpu_flags flags;
67880a648c1SLv Zheng 	int length;
67980a648c1SLv Zheng 
68080a648c1SLv Zheng 	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
681f173a775SLv Zheng 	length = vsnprintf(acpi_gbl_print_buffer,
68280a648c1SLv Zheng 			   sizeof(acpi_gbl_print_buffer), format, args);
683ff2389feSBob Moore 
684dd99cbccSLv Zheng 	(void)fwrite(acpi_gbl_print_buffer, length, 1, file);
68580a648c1SLv Zheng 	acpi_os_release_lock(acpi_gbl_print_lock, flags);
68680a648c1SLv Zheng 
68780a648c1SLv Zheng 	return (length);
68880a648c1SLv Zheng }
68980a648c1SLv Zheng 
69080a648c1SLv Zheng /*******************************************************************************
69180a648c1SLv Zheng  *
692f173a775SLv Zheng  * FUNCTION:    fprintf
69380a648c1SLv Zheng  *
69480a648c1SLv Zheng  * PARAMETERS:  file                - File descriptor
69580a648c1SLv Zheng  *              Format, ...         - Standard printf format
69680a648c1SLv Zheng  *
697ff2389feSBob Moore  * RETURN:      Number of bytes actually written.
69880a648c1SLv Zheng  *
69980a648c1SLv Zheng  * DESCRIPTION: Formatted output to a file.
70080a648c1SLv Zheng  *
70180a648c1SLv Zheng  ******************************************************************************/
70280a648c1SLv Zheng 
fprintf(FILE * file,const char * format,...)703f173a775SLv Zheng int fprintf(FILE * file, const char *format, ...)
70480a648c1SLv Zheng {
70580a648c1SLv Zheng 	va_list args;
70680a648c1SLv Zheng 	int length;
70780a648c1SLv Zheng 
70880a648c1SLv Zheng 	va_start(args, format);
709f173a775SLv Zheng 	length = vfprintf(file, format, args);
71080a648c1SLv Zheng 	va_end(args);
71180a648c1SLv Zheng 
71280a648c1SLv Zheng 	return (length);
71380a648c1SLv Zheng }
71480a648c1SLv Zheng #endif
715