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