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 * 64441e55dSBob Moore * Copyright (C) 2000 - 2021, 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 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 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 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 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 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 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 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; 478*b5e77403SWei 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 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 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 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 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 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 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