162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: utprint - Formatted printing routines
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *****************************************************************************/
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define _COMPONENT          ACPI_UTILITIES
1462306a36Sopenharmony_ciACPI_MODULE_NAME("utprint")
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define ACPI_FORMAT_SIGN            0x01
1762306a36Sopenharmony_ci#define ACPI_FORMAT_SIGN_PLUS       0x02
1862306a36Sopenharmony_ci#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
1962306a36Sopenharmony_ci#define ACPI_FORMAT_ZERO            0x08
2062306a36Sopenharmony_ci#define ACPI_FORMAT_LEFT            0x10
2162306a36Sopenharmony_ci#define ACPI_FORMAT_UPPER           0x20
2262306a36Sopenharmony_ci#define ACPI_FORMAT_PREFIX          0x40
2362306a36Sopenharmony_ci/* Local prototypes */
2462306a36Sopenharmony_cistatic acpi_size
2562306a36Sopenharmony_ciacpi_ut_bound_string_length(const char *string, acpi_size count);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic char *acpi_ut_bound_string_output(char *string, const char *end, char c);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic char *acpi_ut_format_number(char *string,
3062306a36Sopenharmony_ci				   char *end,
3162306a36Sopenharmony_ci				   u64 number,
3262306a36Sopenharmony_ci				   u8 base, s32 width, s32 precision, u8 type);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*******************************************************************************
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * FUNCTION:    acpi_ut_bound_string_length
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci * PARAMETERS:  string              - String with boundary
4162306a36Sopenharmony_ci *              count               - Boundary of the string
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * RETURN:      Length of the string. Less than or equal to Count.
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci * DESCRIPTION: Calculate the length of a string with boundary.
4662306a36Sopenharmony_ci *
4762306a36Sopenharmony_ci ******************************************************************************/
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic acpi_size
5062306a36Sopenharmony_ciacpi_ut_bound_string_length(const char *string, acpi_size count)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	u32 length = 0;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	while (*string && count) {
5562306a36Sopenharmony_ci		length++;
5662306a36Sopenharmony_ci		string++;
5762306a36Sopenharmony_ci		count--;
5862306a36Sopenharmony_ci	}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	return (length);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/*******************************************************************************
6462306a36Sopenharmony_ci *
6562306a36Sopenharmony_ci * FUNCTION:    acpi_ut_bound_string_output
6662306a36Sopenharmony_ci *
6762306a36Sopenharmony_ci * PARAMETERS:  string              - String with boundary
6862306a36Sopenharmony_ci *              end                 - Boundary of the string
6962306a36Sopenharmony_ci *              c                   - Character to be output to the string
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * RETURN:      Updated position for next valid character
7262306a36Sopenharmony_ci *
7362306a36Sopenharmony_ci * DESCRIPTION: Output a character into a string with boundary check.
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci ******************************************************************************/
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic char *acpi_ut_bound_string_output(char *string, const char *end, char c)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	if (string < end) {
8162306a36Sopenharmony_ci		*string = c;
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	++string;
8562306a36Sopenharmony_ci	return (string);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/*******************************************************************************
8962306a36Sopenharmony_ci *
9062306a36Sopenharmony_ci * FUNCTION:    acpi_ut_put_number
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci * PARAMETERS:  string              - Buffer to hold reverse-ordered string
9362306a36Sopenharmony_ci *              number              - Integer to be converted
9462306a36Sopenharmony_ci *              base                - Base of the integer
9562306a36Sopenharmony_ci *              upper               - Whether or not using upper cased digits
9662306a36Sopenharmony_ci *
9762306a36Sopenharmony_ci * RETURN:      Updated position for next valid character
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * DESCRIPTION: Convert an integer into a string, note that, the string holds a
10062306a36Sopenharmony_ci *              reversed ordered number without the trailing zero.
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci ******************************************************************************/
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistatic char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	const char *digits;
10762306a36Sopenharmony_ci	u64 digit_index;
10862306a36Sopenharmony_ci	char *pos;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	pos = string;
11162306a36Sopenharmony_ci	digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	if (number == 0) {
11462306a36Sopenharmony_ci		*(pos++) = '0';
11562306a36Sopenharmony_ci	} else {
11662306a36Sopenharmony_ci		while (number) {
11762306a36Sopenharmony_ci			(void)acpi_ut_divide(number, base, &number,
11862306a36Sopenharmony_ci					     &digit_index);
11962306a36Sopenharmony_ci			*(pos++) = digits[digit_index];
12062306a36Sopenharmony_ci		}
12162306a36Sopenharmony_ci	}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	/* *(Pos++) = '0'; */
12462306a36Sopenharmony_ci	return (pos);
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/*******************************************************************************
12862306a36Sopenharmony_ci *
12962306a36Sopenharmony_ci * FUNCTION:    acpi_ut_scan_number
13062306a36Sopenharmony_ci *
13162306a36Sopenharmony_ci * PARAMETERS:  string              - String buffer
13262306a36Sopenharmony_ci *              number_ptr          - Where the number is returned
13362306a36Sopenharmony_ci *
13462306a36Sopenharmony_ci * RETURN:      Updated position for next valid character
13562306a36Sopenharmony_ci *
13662306a36Sopenharmony_ci * DESCRIPTION: Scan a string for a decimal integer.
13762306a36Sopenharmony_ci *
13862306a36Sopenharmony_ci ******************************************************************************/
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ciconst char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	u64 number = 0;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	while (isdigit((int)*string)) {
14562306a36Sopenharmony_ci		acpi_ut_short_multiply(number, 10, &number);
14662306a36Sopenharmony_ci		number += *(string++) - '0';
14762306a36Sopenharmony_ci	}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	*number_ptr = number;
15062306a36Sopenharmony_ci	return (string);
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/*******************************************************************************
15462306a36Sopenharmony_ci *
15562306a36Sopenharmony_ci * FUNCTION:    acpi_ut_print_number
15662306a36Sopenharmony_ci *
15762306a36Sopenharmony_ci * PARAMETERS:  string              - String buffer
15862306a36Sopenharmony_ci *              number              - The number to be converted
15962306a36Sopenharmony_ci *
16062306a36Sopenharmony_ci * RETURN:      Updated position for next valid character
16162306a36Sopenharmony_ci *
16262306a36Sopenharmony_ci * DESCRIPTION: Print a decimal integer into a string.
16362306a36Sopenharmony_ci *
16462306a36Sopenharmony_ci ******************************************************************************/
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciconst char *acpi_ut_print_number(char *string, u64 number)
16762306a36Sopenharmony_ci{
16862306a36Sopenharmony_ci	char ascii_string[20];
16962306a36Sopenharmony_ci	const char *pos1;
17062306a36Sopenharmony_ci	char *pos2;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
17362306a36Sopenharmony_ci	pos2 = string;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	while (pos1 != ascii_string) {
17662306a36Sopenharmony_ci		*(pos2++) = *(--pos1);
17762306a36Sopenharmony_ci	}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	*pos2 = 0;
18062306a36Sopenharmony_ci	return (string);
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/*******************************************************************************
18462306a36Sopenharmony_ci *
18562306a36Sopenharmony_ci * FUNCTION:    acpi_ut_format_number
18662306a36Sopenharmony_ci *
18762306a36Sopenharmony_ci * PARAMETERS:  string              - String buffer with boundary
18862306a36Sopenharmony_ci *              end                 - Boundary of the string
18962306a36Sopenharmony_ci *              number              - The number to be converted
19062306a36Sopenharmony_ci *              base                - Base of the integer
19162306a36Sopenharmony_ci *              width               - Field width
19262306a36Sopenharmony_ci *              precision           - Precision of the integer
19362306a36Sopenharmony_ci *              type                - Special printing flags
19462306a36Sopenharmony_ci *
19562306a36Sopenharmony_ci * RETURN:      Updated position for next valid character
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * DESCRIPTION: Print an integer into a string with any base and any precision.
19862306a36Sopenharmony_ci *
19962306a36Sopenharmony_ci ******************************************************************************/
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistatic char *acpi_ut_format_number(char *string,
20262306a36Sopenharmony_ci				   char *end,
20362306a36Sopenharmony_ci				   u64 number,
20462306a36Sopenharmony_ci				   u8 base, s32 width, s32 precision, u8 type)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci	char *pos;
20762306a36Sopenharmony_ci	char sign;
20862306a36Sopenharmony_ci	char zero;
20962306a36Sopenharmony_ci	u8 need_prefix;
21062306a36Sopenharmony_ci	u8 upper;
21162306a36Sopenharmony_ci	s32 i;
21262306a36Sopenharmony_ci	char reversed_string[66];
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	/* Parameter validation */
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	if (base < 2 || base > 16) {
21762306a36Sopenharmony_ci		return (NULL);
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	if (type & ACPI_FORMAT_LEFT) {
22162306a36Sopenharmony_ci		type &= ~ACPI_FORMAT_ZERO;
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	need_prefix = ((type & ACPI_FORMAT_PREFIX)
22562306a36Sopenharmony_ci		       && base != 10) ? TRUE : FALSE;
22662306a36Sopenharmony_ci	upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
22762306a36Sopenharmony_ci	zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	/* Calculate size according to sign and prefix */
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	sign = '\0';
23262306a36Sopenharmony_ci	if (type & ACPI_FORMAT_SIGN) {
23362306a36Sopenharmony_ci		if ((s64)number < 0) {
23462306a36Sopenharmony_ci			sign = '-';
23562306a36Sopenharmony_ci			number = -(s64)number;
23662306a36Sopenharmony_ci			width--;
23762306a36Sopenharmony_ci		} else if (type & ACPI_FORMAT_SIGN_PLUS) {
23862306a36Sopenharmony_ci			sign = '+';
23962306a36Sopenharmony_ci			width--;
24062306a36Sopenharmony_ci		} else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
24162306a36Sopenharmony_ci			sign = ' ';
24262306a36Sopenharmony_ci			width--;
24362306a36Sopenharmony_ci		}
24462306a36Sopenharmony_ci	}
24562306a36Sopenharmony_ci	if (need_prefix) {
24662306a36Sopenharmony_ci		width--;
24762306a36Sopenharmony_ci		if (base == 16) {
24862306a36Sopenharmony_ci			width--;
24962306a36Sopenharmony_ci		}
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	/* Generate full string in reverse order */
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	pos = acpi_ut_put_number(reversed_string, number, base, upper);
25562306a36Sopenharmony_ci	i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	/* Printing 100 using %2d gives "100", not "00" */
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	if (i > precision) {
26062306a36Sopenharmony_ci		precision = i;
26162306a36Sopenharmony_ci	}
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	width -= precision;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	/* Output the string */
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
26862306a36Sopenharmony_ci		while (--width >= 0) {
26962306a36Sopenharmony_ci			string = acpi_ut_bound_string_output(string, end, ' ');
27062306a36Sopenharmony_ci		}
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci	if (sign) {
27362306a36Sopenharmony_ci		string = acpi_ut_bound_string_output(string, end, sign);
27462306a36Sopenharmony_ci	}
27562306a36Sopenharmony_ci	if (need_prefix) {
27662306a36Sopenharmony_ci		string = acpi_ut_bound_string_output(string, end, '0');
27762306a36Sopenharmony_ci		if (base == 16) {
27862306a36Sopenharmony_ci			string =
27962306a36Sopenharmony_ci			    acpi_ut_bound_string_output(string, end,
28062306a36Sopenharmony_ci							upper ? 'X' : 'x');
28162306a36Sopenharmony_ci		}
28262306a36Sopenharmony_ci	}
28362306a36Sopenharmony_ci	if (!(type & ACPI_FORMAT_LEFT)) {
28462306a36Sopenharmony_ci		while (--width >= 0) {
28562306a36Sopenharmony_ci			string = acpi_ut_bound_string_output(string, end, zero);
28662306a36Sopenharmony_ci		}
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	while (i <= --precision) {
29062306a36Sopenharmony_ci		string = acpi_ut_bound_string_output(string, end, '0');
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci	while (--i >= 0) {
29362306a36Sopenharmony_ci		string = acpi_ut_bound_string_output(string, end,
29462306a36Sopenharmony_ci						     reversed_string[i]);
29562306a36Sopenharmony_ci	}
29662306a36Sopenharmony_ci	while (--width >= 0) {
29762306a36Sopenharmony_ci		string = acpi_ut_bound_string_output(string, end, ' ');
29862306a36Sopenharmony_ci	}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	return (string);
30162306a36Sopenharmony_ci}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci/*******************************************************************************
30462306a36Sopenharmony_ci *
30562306a36Sopenharmony_ci * FUNCTION:    vsnprintf
30662306a36Sopenharmony_ci *
30762306a36Sopenharmony_ci * PARAMETERS:  string              - String with boundary
30862306a36Sopenharmony_ci *              size                - Boundary of the string
30962306a36Sopenharmony_ci *              format              - Standard printf format
31062306a36Sopenharmony_ci *              args                - Argument list
31162306a36Sopenharmony_ci *
31262306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
31362306a36Sopenharmony_ci *
31462306a36Sopenharmony_ci * DESCRIPTION: Formatted output to a string using argument list pointer.
31562306a36Sopenharmony_ci *
31662306a36Sopenharmony_ci ******************************************************************************/
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ciint vsnprintf(char *string, acpi_size size, const char *format, va_list args)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	u8 base;
32162306a36Sopenharmony_ci	u8 type;
32262306a36Sopenharmony_ci	s32 width;
32362306a36Sopenharmony_ci	s32 precision;
32462306a36Sopenharmony_ci	char qualifier;
32562306a36Sopenharmony_ci	u64 number;
32662306a36Sopenharmony_ci	char *pos;
32762306a36Sopenharmony_ci	char *end;
32862306a36Sopenharmony_ci	char c;
32962306a36Sopenharmony_ci	const char *s;
33062306a36Sopenharmony_ci	const void *p;
33162306a36Sopenharmony_ci	s32 length;
33262306a36Sopenharmony_ci	int i;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	pos = string;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	if (size != ACPI_UINT32_MAX) {
33762306a36Sopenharmony_ci		end = string + size;
33862306a36Sopenharmony_ci	} else {
33962306a36Sopenharmony_ci		end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
34062306a36Sopenharmony_ci	}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	for (; *format; ++format) {
34362306a36Sopenharmony_ci		if (*format != '%') {
34462306a36Sopenharmony_ci			pos = acpi_ut_bound_string_output(pos, end, *format);
34562306a36Sopenharmony_ci			continue;
34662306a36Sopenharmony_ci		}
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci		type = 0;
34962306a36Sopenharmony_ci		base = 10;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci		/* Process sign */
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci		do {
35462306a36Sopenharmony_ci			++format;
35562306a36Sopenharmony_ci			if (*format == '#') {
35662306a36Sopenharmony_ci				type |= ACPI_FORMAT_PREFIX;
35762306a36Sopenharmony_ci			} else if (*format == '0') {
35862306a36Sopenharmony_ci				type |= ACPI_FORMAT_ZERO;
35962306a36Sopenharmony_ci			} else if (*format == '+') {
36062306a36Sopenharmony_ci				type |= ACPI_FORMAT_SIGN_PLUS;
36162306a36Sopenharmony_ci			} else if (*format == ' ') {
36262306a36Sopenharmony_ci				type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
36362306a36Sopenharmony_ci			} else if (*format == '-') {
36462306a36Sopenharmony_ci				type |= ACPI_FORMAT_LEFT;
36562306a36Sopenharmony_ci			} else {
36662306a36Sopenharmony_ci				break;
36762306a36Sopenharmony_ci			}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci		} while (1);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		/* Process width */
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci		width = -1;
37462306a36Sopenharmony_ci		if (isdigit((int)*format)) {
37562306a36Sopenharmony_ci			format = acpi_ut_scan_number(format, &number);
37662306a36Sopenharmony_ci			width = (s32)number;
37762306a36Sopenharmony_ci		} else if (*format == '*') {
37862306a36Sopenharmony_ci			++format;
37962306a36Sopenharmony_ci			width = va_arg(args, int);
38062306a36Sopenharmony_ci			if (width < 0) {
38162306a36Sopenharmony_ci				width = -width;
38262306a36Sopenharmony_ci				type |= ACPI_FORMAT_LEFT;
38362306a36Sopenharmony_ci			}
38462306a36Sopenharmony_ci		}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci		/* Process precision */
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci		precision = -1;
38962306a36Sopenharmony_ci		if (*format == '.') {
39062306a36Sopenharmony_ci			++format;
39162306a36Sopenharmony_ci			if (isdigit((int)*format)) {
39262306a36Sopenharmony_ci				format = acpi_ut_scan_number(format, &number);
39362306a36Sopenharmony_ci				precision = (s32)number;
39462306a36Sopenharmony_ci			} else if (*format == '*') {
39562306a36Sopenharmony_ci				++format;
39662306a36Sopenharmony_ci				precision = va_arg(args, int);
39762306a36Sopenharmony_ci			}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci			if (precision < 0) {
40062306a36Sopenharmony_ci				precision = 0;
40162306a36Sopenharmony_ci			}
40262306a36Sopenharmony_ci		}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci		/* Process qualifier */
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci		qualifier = -1;
40762306a36Sopenharmony_ci		if (*format == 'h' || *format == 'l' || *format == 'L') {
40862306a36Sopenharmony_ci			qualifier = *format;
40962306a36Sopenharmony_ci			++format;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci			if (qualifier == 'l' && *format == 'l') {
41262306a36Sopenharmony_ci				qualifier = 'L';
41362306a36Sopenharmony_ci				++format;
41462306a36Sopenharmony_ci			}
41562306a36Sopenharmony_ci		}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci		switch (*format) {
41862306a36Sopenharmony_ci		case '%':
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci			pos = acpi_ut_bound_string_output(pos, end, '%');
42162306a36Sopenharmony_ci			continue;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci		case 'c':
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci			if (!(type & ACPI_FORMAT_LEFT)) {
42662306a36Sopenharmony_ci				while (--width > 0) {
42762306a36Sopenharmony_ci					pos =
42862306a36Sopenharmony_ci					    acpi_ut_bound_string_output(pos,
42962306a36Sopenharmony_ci									end,
43062306a36Sopenharmony_ci									' ');
43162306a36Sopenharmony_ci				}
43262306a36Sopenharmony_ci			}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci			c = (char)va_arg(args, int);
43562306a36Sopenharmony_ci			pos = acpi_ut_bound_string_output(pos, end, c);
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci			while (--width > 0) {
43862306a36Sopenharmony_ci				pos =
43962306a36Sopenharmony_ci				    acpi_ut_bound_string_output(pos, end, ' ');
44062306a36Sopenharmony_ci			}
44162306a36Sopenharmony_ci			continue;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci		case 's':
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci			s = va_arg(args, char *);
44662306a36Sopenharmony_ci			if (!s) {
44762306a36Sopenharmony_ci				s = "<NULL>";
44862306a36Sopenharmony_ci			}
44962306a36Sopenharmony_ci			length = (s32)acpi_ut_bound_string_length(s, precision);
45062306a36Sopenharmony_ci			if (!(type & ACPI_FORMAT_LEFT)) {
45162306a36Sopenharmony_ci				while (length < width--) {
45262306a36Sopenharmony_ci					pos =
45362306a36Sopenharmony_ci					    acpi_ut_bound_string_output(pos,
45462306a36Sopenharmony_ci									end,
45562306a36Sopenharmony_ci									' ');
45662306a36Sopenharmony_ci				}
45762306a36Sopenharmony_ci			}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci			for (i = 0; i < length; ++i) {
46062306a36Sopenharmony_ci				pos = acpi_ut_bound_string_output(pos, end, *s);
46162306a36Sopenharmony_ci				++s;
46262306a36Sopenharmony_ci			}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci			while (length < width--) {
46562306a36Sopenharmony_ci				pos =
46662306a36Sopenharmony_ci				    acpi_ut_bound_string_output(pos, end, ' ');
46762306a36Sopenharmony_ci			}
46862306a36Sopenharmony_ci			continue;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci		case 'o':
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci			base = 8;
47362306a36Sopenharmony_ci			break;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci		case 'X':
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci			type |= ACPI_FORMAT_UPPER;
47862306a36Sopenharmony_ci			ACPI_FALLTHROUGH;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci		case 'x':
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci			base = 16;
48362306a36Sopenharmony_ci			break;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci		case 'd':
48662306a36Sopenharmony_ci		case 'i':
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci			type |= ACPI_FORMAT_SIGN;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci		case 'u':
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci			break;
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci		case 'p':
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci			if (width == -1) {
49762306a36Sopenharmony_ci				width = 2 * sizeof(void *);
49862306a36Sopenharmony_ci				type |= ACPI_FORMAT_ZERO;
49962306a36Sopenharmony_ci			}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci			p = va_arg(args, void *);
50262306a36Sopenharmony_ci			pos =
50362306a36Sopenharmony_ci			    acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
50462306a36Sopenharmony_ci						  16, width, precision, type);
50562306a36Sopenharmony_ci			continue;
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci		default:
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci			pos = acpi_ut_bound_string_output(pos, end, '%');
51062306a36Sopenharmony_ci			if (*format) {
51162306a36Sopenharmony_ci				pos =
51262306a36Sopenharmony_ci				    acpi_ut_bound_string_output(pos, end,
51362306a36Sopenharmony_ci								*format);
51462306a36Sopenharmony_ci			} else {
51562306a36Sopenharmony_ci				--format;
51662306a36Sopenharmony_ci			}
51762306a36Sopenharmony_ci			continue;
51862306a36Sopenharmony_ci		}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci		if (qualifier == 'L') {
52162306a36Sopenharmony_ci			number = va_arg(args, u64);
52262306a36Sopenharmony_ci			if (type & ACPI_FORMAT_SIGN) {
52362306a36Sopenharmony_ci				number = (s64)number;
52462306a36Sopenharmony_ci			}
52562306a36Sopenharmony_ci		} else if (qualifier == 'l') {
52662306a36Sopenharmony_ci			number = va_arg(args, unsigned long);
52762306a36Sopenharmony_ci			if (type & ACPI_FORMAT_SIGN) {
52862306a36Sopenharmony_ci				number = (s32)number;
52962306a36Sopenharmony_ci			}
53062306a36Sopenharmony_ci		} else if (qualifier == 'h') {
53162306a36Sopenharmony_ci			number = (u16)va_arg(args, int);
53262306a36Sopenharmony_ci			if (type & ACPI_FORMAT_SIGN) {
53362306a36Sopenharmony_ci				number = (s16)number;
53462306a36Sopenharmony_ci			}
53562306a36Sopenharmony_ci		} else {
53662306a36Sopenharmony_ci			number = va_arg(args, unsigned int);
53762306a36Sopenharmony_ci			if (type & ACPI_FORMAT_SIGN) {
53862306a36Sopenharmony_ci				number = (signed int)number;
53962306a36Sopenharmony_ci			}
54062306a36Sopenharmony_ci		}
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci		pos = acpi_ut_format_number(pos, end, number, base,
54362306a36Sopenharmony_ci					    width, precision, type);
54462306a36Sopenharmony_ci	}
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	if (size > 0) {
54762306a36Sopenharmony_ci		if (pos < end) {
54862306a36Sopenharmony_ci			*pos = '\0';
54962306a36Sopenharmony_ci		} else {
55062306a36Sopenharmony_ci			end[-1] = '\0';
55162306a36Sopenharmony_ci		}
55262306a36Sopenharmony_ci	}
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	return ((int)ACPI_PTR_DIFF(pos, string));
55562306a36Sopenharmony_ci}
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci/*******************************************************************************
55862306a36Sopenharmony_ci *
55962306a36Sopenharmony_ci * FUNCTION:    snprintf
56062306a36Sopenharmony_ci *
56162306a36Sopenharmony_ci * PARAMETERS:  string              - String with boundary
56262306a36Sopenharmony_ci *              size                - Boundary of the string
56362306a36Sopenharmony_ci *              Format, ...         - Standard printf format
56462306a36Sopenharmony_ci *
56562306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
56662306a36Sopenharmony_ci *
56762306a36Sopenharmony_ci * DESCRIPTION: Formatted output to a string.
56862306a36Sopenharmony_ci *
56962306a36Sopenharmony_ci ******************************************************************************/
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ciint snprintf(char *string, acpi_size size, const char *format, ...)
57262306a36Sopenharmony_ci{
57362306a36Sopenharmony_ci	va_list args;
57462306a36Sopenharmony_ci	int length;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	va_start(args, format);
57762306a36Sopenharmony_ci	length = vsnprintf(string, size, format, args);
57862306a36Sopenharmony_ci	va_end(args);
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_ci	return (length);
58162306a36Sopenharmony_ci}
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci/*******************************************************************************
58462306a36Sopenharmony_ci *
58562306a36Sopenharmony_ci * FUNCTION:    sprintf
58662306a36Sopenharmony_ci *
58762306a36Sopenharmony_ci * PARAMETERS:  string              - String with boundary
58862306a36Sopenharmony_ci *              Format, ...         - Standard printf format
58962306a36Sopenharmony_ci *
59062306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
59162306a36Sopenharmony_ci *
59262306a36Sopenharmony_ci * DESCRIPTION: Formatted output to a string.
59362306a36Sopenharmony_ci *
59462306a36Sopenharmony_ci ******************************************************************************/
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ciint sprintf(char *string, const char *format, ...)
59762306a36Sopenharmony_ci{
59862306a36Sopenharmony_ci	va_list args;
59962306a36Sopenharmony_ci	int length;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	va_start(args, format);
60262306a36Sopenharmony_ci	length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
60362306a36Sopenharmony_ci	va_end(args);
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	return (length);
60662306a36Sopenharmony_ci}
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci#ifdef ACPI_APPLICATION
60962306a36Sopenharmony_ci/*******************************************************************************
61062306a36Sopenharmony_ci *
61162306a36Sopenharmony_ci * FUNCTION:    vprintf
61262306a36Sopenharmony_ci *
61362306a36Sopenharmony_ci * PARAMETERS:  format              - Standard printf format
61462306a36Sopenharmony_ci *              args                - Argument list
61562306a36Sopenharmony_ci *
61662306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
61762306a36Sopenharmony_ci *
61862306a36Sopenharmony_ci * DESCRIPTION: Formatted output to stdout using argument list pointer.
61962306a36Sopenharmony_ci *
62062306a36Sopenharmony_ci ******************************************************************************/
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ciint vprintf(const char *format, va_list args)
62362306a36Sopenharmony_ci{
62462306a36Sopenharmony_ci	acpi_cpu_flags flags;
62562306a36Sopenharmony_ci	int length;
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
62862306a36Sopenharmony_ci	length = vsnprintf(acpi_gbl_print_buffer,
62962306a36Sopenharmony_ci			   sizeof(acpi_gbl_print_buffer), format, args);
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	(void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
63262306a36Sopenharmony_ci	acpi_os_release_lock(acpi_gbl_print_lock, flags);
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	return (length);
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci/*******************************************************************************
63862306a36Sopenharmony_ci *
63962306a36Sopenharmony_ci * FUNCTION:    printf
64062306a36Sopenharmony_ci *
64162306a36Sopenharmony_ci * PARAMETERS:  Format, ...         - Standard printf format
64262306a36Sopenharmony_ci *
64362306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
64462306a36Sopenharmony_ci *
64562306a36Sopenharmony_ci * DESCRIPTION: Formatted output to stdout.
64662306a36Sopenharmony_ci *
64762306a36Sopenharmony_ci ******************************************************************************/
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ciint printf(const char *format, ...)
65062306a36Sopenharmony_ci{
65162306a36Sopenharmony_ci	va_list args;
65262306a36Sopenharmony_ci	int length;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	va_start(args, format);
65562306a36Sopenharmony_ci	length = vprintf(format, args);
65662306a36Sopenharmony_ci	va_end(args);
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	return (length);
65962306a36Sopenharmony_ci}
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci/*******************************************************************************
66262306a36Sopenharmony_ci *
66362306a36Sopenharmony_ci * FUNCTION:    vfprintf
66462306a36Sopenharmony_ci *
66562306a36Sopenharmony_ci * PARAMETERS:  file                - File descriptor
66662306a36Sopenharmony_ci *              format              - Standard printf format
66762306a36Sopenharmony_ci *              args                - Argument list
66862306a36Sopenharmony_ci *
66962306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
67062306a36Sopenharmony_ci *
67162306a36Sopenharmony_ci * DESCRIPTION: Formatted output to a file using argument list pointer.
67262306a36Sopenharmony_ci *
67362306a36Sopenharmony_ci ******************************************************************************/
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ciint vfprintf(FILE * file, const char *format, va_list args)
67662306a36Sopenharmony_ci{
67762306a36Sopenharmony_ci	acpi_cpu_flags flags;
67862306a36Sopenharmony_ci	int length;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
68162306a36Sopenharmony_ci	length = vsnprintf(acpi_gbl_print_buffer,
68262306a36Sopenharmony_ci			   sizeof(acpi_gbl_print_buffer), format, args);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	(void)fwrite(acpi_gbl_print_buffer, length, 1, file);
68562306a36Sopenharmony_ci	acpi_os_release_lock(acpi_gbl_print_lock, flags);
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	return (length);
68862306a36Sopenharmony_ci}
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci/*******************************************************************************
69162306a36Sopenharmony_ci *
69262306a36Sopenharmony_ci * FUNCTION:    fprintf
69362306a36Sopenharmony_ci *
69462306a36Sopenharmony_ci * PARAMETERS:  file                - File descriptor
69562306a36Sopenharmony_ci *              Format, ...         - Standard printf format
69662306a36Sopenharmony_ci *
69762306a36Sopenharmony_ci * RETURN:      Number of bytes actually written.
69862306a36Sopenharmony_ci *
69962306a36Sopenharmony_ci * DESCRIPTION: Formatted output to a file.
70062306a36Sopenharmony_ci *
70162306a36Sopenharmony_ci ******************************************************************************/
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ciint fprintf(FILE * file, const char *format, ...)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	va_list args;
70662306a36Sopenharmony_ci	int length;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	va_start(args, format);
70962306a36Sopenharmony_ci	length = vfprintf(file, format, args);
71062306a36Sopenharmony_ci	va_end(args);
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	return (length);
71362306a36Sopenharmony_ci}
71462306a36Sopenharmony_ci#endif
715