| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | /******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Module Name: utprint - Formatted printing routines | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (C) 2000 - 2014, Intel Corp. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  * are met: | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions, and the following disclaimer, | 
					
						
							|  |  |  |  *    without modification. | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 
					
						
							|  |  |  |  *    substantially similar to the "NO WARRANTY" disclaimer below | 
					
						
							|  |  |  |  *    ("Disclaimer") and any redistribution must be conditioned upon | 
					
						
							|  |  |  |  *    including a substantially similar Disclaimer requirement for further | 
					
						
							|  |  |  |  *    binary redistribution. | 
					
						
							|  |  |  |  * 3. Neither the names of the above-listed copyright holders nor the names | 
					
						
							|  |  |  |  *    of any contributors may be used to endorse or promote products derived | 
					
						
							|  |  |  |  *    from this software without specific prior written permission. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Alternatively, this software may be distributed under the terms of the | 
					
						
							|  |  |  |  * GNU General Public License ("GPL") version 2 as published by the Free | 
					
						
							|  |  |  |  * Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NO WARRANTY | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
					
						
							|  |  |  |  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
					
						
							|  |  |  |  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 
					
						
							|  |  |  |  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
					
						
							|  |  |  |  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
					
						
							|  |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
					
						
							|  |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 
					
						
							|  |  |  |  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 
					
						
							|  |  |  |  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
					
						
							|  |  |  |  * POSSIBILITY OF SUCH DAMAGES. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <acpi/acpi.h>
 | 
					
						
							|  |  |  | #include "accommon.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _COMPONENT          ACPI_UTILITIES
 | 
					
						
							|  |  |  | ACPI_MODULE_NAME("utprint") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_SIGN            0x01
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_SIGN_PLUS       0x02
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_ZERO            0x08
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_LEFT            0x10
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_UPPER           0x20
 | 
					
						
							|  |  |  | #define ACPI_FORMAT_PREFIX          0x40
 | 
					
						
							|  |  |  | /* Local prototypes */ | 
					
						
							|  |  |  | static acpi_size | 
					
						
							|  |  |  | acpi_ut_bound_string_length(const char *string, acpi_size count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_bound_string_output(char *string, const char *end, char c); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_format_number(char *string, | 
					
						
							|  |  |  | 				   char *end, | 
					
						
							|  |  |  | 				   u64 number, | 
					
						
							|  |  |  | 				   u8 base, s32 width, s32 precision, u8 type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | /* Module globals */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef"; | 
					
						
							|  |  |  | static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_bound_string_length | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String with boundary | 
					
						
							|  |  |  |  *              count               - Boundary of the string | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  |  * RETURN:      Length of the string. Less than or equal to Count. | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Calculate the length of a string with boundary. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static acpi_size | 
					
						
							|  |  |  | acpi_ut_bound_string_length(const char *string, acpi_size count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 length = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (*string && count) { | 
					
						
							|  |  |  | 		length++; | 
					
						
							|  |  |  | 		string++; | 
					
						
							|  |  |  | 		count--; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_bound_string_output | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String with boundary | 
					
						
							|  |  |  |  *              end                 - Boundary of the string | 
					
						
							|  |  |  |  *              c                   - Character to be output to the string | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Updated position for next valid character | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Output a character into a string with boundary check. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_bound_string_output(char *string, const char *end, char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (string < end) { | 
					
						
							|  |  |  | 		*string = c; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	++string; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	return (string); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_put_number | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - Buffer to hold reverse-ordered string | 
					
						
							|  |  |  |  *              number              - Integer to be converted | 
					
						
							|  |  |  |  *              base                - Base of the integer | 
					
						
							|  |  |  |  *              upper               - Whether or not using upper cased digits | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Updated position for next valid character | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Convert an integer into a string, note that, the string holds a | 
					
						
							|  |  |  |  *              reversed ordered number without the trailing zero. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *digits; | 
					
						
							|  |  |  | 	u64 digit_index; | 
					
						
							|  |  |  | 	char *pos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pos = string; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (number == 0) { | 
					
						
							|  |  |  | 		*(pos++) = '0'; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		while (number) { | 
					
						
							|  |  |  | 			(void)acpi_ut_divide(number, base, &number, | 
					
						
							|  |  |  | 					     &digit_index); | 
					
						
							|  |  |  | 			*(pos++) = digits[digit_index]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	/* *(Pos++) = '0'; */ | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	return (pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_scan_number | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String buffer | 
					
						
							|  |  |  |  *              number_ptr          - Where the number is returned | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Updated position for next valid character | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Scan a string for a decimal integer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *acpi_ut_scan_number(const char *string, u64 *number_ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u64 number = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (ACPI_IS_DIGIT(*string)) { | 
					
						
							|  |  |  | 		number *= 10; | 
					
						
							|  |  |  | 		number += *(string++) - '0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	*number_ptr = number; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	return (string); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_print_number | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String buffer | 
					
						
							|  |  |  |  *              number              - The number to be converted | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Updated position for next valid character | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Print a decimal integer into a string. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *acpi_ut_print_number(char *string, u64 number) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char ascii_string[20]; | 
					
						
							|  |  |  | 	const char *pos1; | 
					
						
							|  |  |  | 	char *pos2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE); | 
					
						
							|  |  |  | 	pos2 = string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (pos1 != ascii_string) { | 
					
						
							|  |  |  | 		*(pos2++) = *(--pos1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	*pos2 = 0; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	return (string); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_format_number | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String buffer with boundary | 
					
						
							|  |  |  |  *              end                 - Boundary of the string | 
					
						
							|  |  |  |  *              number              - The number to be converted | 
					
						
							|  |  |  |  *              base                - Base of the integer | 
					
						
							|  |  |  |  *              width               - Field width | 
					
						
							|  |  |  |  *              precision           - Precision of the integer | 
					
						
							|  |  |  |  *              type                - Special printing flags | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * RETURN:      Updated position for next valid character | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Print an integer into a string with any base and any precision. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *acpi_ut_format_number(char *string, | 
					
						
							|  |  |  | 				   char *end, | 
					
						
							|  |  |  | 				   u64 number, | 
					
						
							|  |  |  | 				   u8 base, s32 width, s32 precision, u8 type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-30 12:20:26 +08:00
										 |  |  | 	char *pos; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	char sign; | 
					
						
							|  |  |  | 	char zero; | 
					
						
							|  |  |  | 	u8 need_prefix; | 
					
						
							|  |  |  | 	u8 upper; | 
					
						
							|  |  |  | 	s32 i; | 
					
						
							|  |  |  | 	char reversed_string[66]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 	/* Parameter validation */ | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (base < 2 || base > 16) { | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 		return (NULL); | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	if (type & ACPI_FORMAT_LEFT) { | 
					
						
							|  |  |  | 		type &= ~ACPI_FORMAT_ZERO; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	need_prefix = ((type & ACPI_FORMAT_PREFIX) | 
					
						
							|  |  |  | 		       && base != 10) ? TRUE : FALSE; | 
					
						
							|  |  |  | 	upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE; | 
					
						
							|  |  |  | 	zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' '; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Calculate size according to sign and prefix */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sign = '\0'; | 
					
						
							|  |  |  | 	if (type & ACPI_FORMAT_SIGN) { | 
					
						
							|  |  |  | 		if ((s64) number < 0) { | 
					
						
							|  |  |  | 			sign = '-'; | 
					
						
							|  |  |  | 			number = -(s64) number; | 
					
						
							|  |  |  | 			width--; | 
					
						
							|  |  |  | 		} else if (type & ACPI_FORMAT_SIGN_PLUS) { | 
					
						
							|  |  |  | 			sign = '+'; | 
					
						
							|  |  |  | 			width--; | 
					
						
							|  |  |  | 		} else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) { | 
					
						
							|  |  |  | 			sign = ' '; | 
					
						
							|  |  |  | 			width--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (need_prefix) { | 
					
						
							|  |  |  | 		width--; | 
					
						
							|  |  |  | 		if (base == 16) { | 
					
						
							|  |  |  | 			width--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Generate full string in reverse order */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:20:26 +08:00
										 |  |  | 	pos = acpi_ut_put_number(reversed_string, number, base, upper); | 
					
						
							|  |  |  | 	i = ACPI_PTR_DIFF(pos, reversed_string); | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Printing 100 using %2d gives "100", not "00" */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (i > precision) { | 
					
						
							|  |  |  | 		precision = i; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	width -= precision; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Output the string */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) { | 
					
						
							|  |  |  | 		while (--width >= 0) { | 
					
						
							|  |  |  | 			string = acpi_ut_bound_string_output(string, end, ' '); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (sign) { | 
					
						
							|  |  |  | 		string = acpi_ut_bound_string_output(string, end, sign); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (need_prefix) { | 
					
						
							|  |  |  | 		string = acpi_ut_bound_string_output(string, end, '0'); | 
					
						
							|  |  |  | 		if (base == 16) { | 
					
						
							|  |  |  | 			string = acpi_ut_bound_string_output(string, end, | 
					
						
							|  |  |  | 							     upper ? 'X' : 'x'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!(type & ACPI_FORMAT_LEFT)) { | 
					
						
							|  |  |  | 		while (--width >= 0) { | 
					
						
							|  |  |  | 			string = acpi_ut_bound_string_output(string, end, zero); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	while (i <= --precision) { | 
					
						
							|  |  |  | 		string = acpi_ut_bound_string_output(string, end, '0'); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (--i >= 0) { | 
					
						
							|  |  |  | 		string = acpi_ut_bound_string_output(string, end, | 
					
						
							|  |  |  | 						     reversed_string[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (--width >= 0) { | 
					
						
							|  |  |  | 		string = acpi_ut_bound_string_output(string, end, ' '); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (string); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_vsnprintf | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String with boundary | 
					
						
							|  |  |  |  *              size                - Boundary of the string | 
					
						
							|  |  |  |  *              format              - Standard printf format | 
					
						
							|  |  |  |  *              args                - Argument list | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  |  * RETURN:      Number of bytes actually written. | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Formatted output to a string using argument list pointer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | acpi_ut_vsnprintf(char *string, | 
					
						
							|  |  |  | 		  acpi_size size, const char *format, va_list args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 base = 10; | 
					
						
							|  |  |  | 	u8 type = 0; | 
					
						
							|  |  |  | 	s32 width = -1; | 
					
						
							|  |  |  | 	s32 precision = -1; | 
					
						
							|  |  |  | 	char qualifier = 0; | 
					
						
							|  |  |  | 	u64 number; | 
					
						
							|  |  |  | 	char *pos; | 
					
						
							|  |  |  | 	char *end; | 
					
						
							|  |  |  | 	char c; | 
					
						
							|  |  |  | 	const char *s; | 
					
						
							|  |  |  | 	const void *p; | 
					
						
							|  |  |  | 	s32 length; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pos = string; | 
					
						
							|  |  |  | 	end = string + size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (; *format; ++format) { | 
					
						
							|  |  |  | 		if (*format != '%') { | 
					
						
							|  |  |  | 			pos = acpi_ut_bound_string_output(pos, end, *format); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Process sign */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			++format; | 
					
						
							|  |  |  | 			if (*format == '#') { | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_PREFIX; | 
					
						
							|  |  |  | 			} else if (*format == '0') { | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_ZERO; | 
					
						
							|  |  |  | 			} else if (*format == '+') { | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_SIGN_PLUS; | 
					
						
							|  |  |  | 			} else if (*format == ' ') { | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_SIGN_PLUS_SPACE; | 
					
						
							|  |  |  | 			} else if (*format == '-') { | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_LEFT; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} while (1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Process width */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:21:07 +08:00
										 |  |  | 		width = -1; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 		if (ACPI_IS_DIGIT(*format)) { | 
					
						
							|  |  |  | 			format = acpi_ut_scan_number(format, &number); | 
					
						
							|  |  |  | 			width = (s32) number; | 
					
						
							|  |  |  | 		} else if (*format == '*') { | 
					
						
							|  |  |  | 			++format; | 
					
						
							|  |  |  | 			width = va_arg(args, int); | 
					
						
							|  |  |  | 			if (width < 0) { | 
					
						
							|  |  |  | 				width = -width; | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_LEFT; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Process precision */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:21:07 +08:00
										 |  |  | 		precision = -1; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 		if (*format == '.') { | 
					
						
							|  |  |  | 			++format; | 
					
						
							|  |  |  | 			if (ACPI_IS_DIGIT(*format)) { | 
					
						
							|  |  |  | 				format = acpi_ut_scan_number(format, &number); | 
					
						
							|  |  |  | 				precision = (s32) number; | 
					
						
							|  |  |  | 			} else if (*format == '*') { | 
					
						
							|  |  |  | 				++format; | 
					
						
							|  |  |  | 				precision = va_arg(args, int); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (precision < 0) { | 
					
						
							|  |  |  | 				precision = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Process qualifier */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:21:07 +08:00
										 |  |  | 		qualifier = -1; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 		if (*format == 'h' || *format == 'l' || *format == 'L') { | 
					
						
							|  |  |  | 			qualifier = *format; | 
					
						
							|  |  |  | 			++format; | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 			if (qualifier == 'l' && *format == 'l') { | 
					
						
							|  |  |  | 				qualifier = 'L'; | 
					
						
							|  |  |  | 				++format; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch (*format) { | 
					
						
							|  |  |  | 		case '%': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			pos = acpi_ut_bound_string_output(pos, end, '%'); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'c': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!(type & ACPI_FORMAT_LEFT)) { | 
					
						
							|  |  |  | 				while (--width > 0) { | 
					
						
							|  |  |  | 					pos = | 
					
						
							|  |  |  | 					    acpi_ut_bound_string_output(pos, | 
					
						
							|  |  |  | 									end, | 
					
						
							|  |  |  | 									' '); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 			c = (char)va_arg(args, int); | 
					
						
							|  |  |  | 			pos = acpi_ut_bound_string_output(pos, end, c); | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 			while (--width > 0) { | 
					
						
							|  |  |  | 				pos = | 
					
						
							|  |  |  | 				    acpi_ut_bound_string_output(pos, end, ' '); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 's': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			s = va_arg(args, char *); | 
					
						
							|  |  |  | 			if (!s) { | 
					
						
							|  |  |  | 				s = "<NULL>"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			length = acpi_ut_bound_string_length(s, precision); | 
					
						
							|  |  |  | 			if (!(type & ACPI_FORMAT_LEFT)) { | 
					
						
							|  |  |  | 				while (length < width--) { | 
					
						
							|  |  |  | 					pos = | 
					
						
							|  |  |  | 					    acpi_ut_bound_string_output(pos, | 
					
						
							|  |  |  | 									end, | 
					
						
							|  |  |  | 									' '); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for (i = 0; i < length; ++i) { | 
					
						
							|  |  |  | 				pos = acpi_ut_bound_string_output(pos, end, *s); | 
					
						
							|  |  |  | 				++s; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			while (length < width--) { | 
					
						
							|  |  |  | 				pos = | 
					
						
							|  |  |  | 				    acpi_ut_bound_string_output(pos, end, ' '); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'o': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			base = 8; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'X': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			type |= ACPI_FORMAT_UPPER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'x': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			base = 16; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'd': | 
					
						
							|  |  |  | 		case 'i': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			type |= ACPI_FORMAT_SIGN; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'u': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'p': | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (width == -1) { | 
					
						
							|  |  |  | 				width = 2 * sizeof(void *); | 
					
						
							|  |  |  | 				type |= ACPI_FORMAT_ZERO; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 			p = va_arg(args, void *); | 
					
						
							|  |  |  | 			pos = acpi_ut_format_number(pos, end, | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 						    ACPI_TO_INTEGER(p), 16, | 
					
						
							|  |  |  | 						    width, precision, type); | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			pos = acpi_ut_bound_string_output(pos, end, '%'); | 
					
						
							|  |  |  | 			if (*format) { | 
					
						
							|  |  |  | 				pos = | 
					
						
							|  |  |  | 				    acpi_ut_bound_string_output(pos, end, | 
					
						
							|  |  |  | 								*format); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				--format; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (qualifier == 'L') { | 
					
						
							|  |  |  | 			number = va_arg(args, u64); | 
					
						
							|  |  |  | 			if (type & ACPI_FORMAT_SIGN) { | 
					
						
							|  |  |  | 				number = (s64) number; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (qualifier == 'l') { | 
					
						
							|  |  |  | 			number = va_arg(args, unsigned long); | 
					
						
							|  |  |  | 			if (type & ACPI_FORMAT_SIGN) { | 
					
						
							|  |  |  | 				number = (s32) number; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (qualifier == 'h') { | 
					
						
							|  |  |  | 			number = (u16)va_arg(args, int); | 
					
						
							|  |  |  | 			if (type & ACPI_FORMAT_SIGN) { | 
					
						
							|  |  |  | 				number = (s16) number; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			number = va_arg(args, unsigned int); | 
					
						
							|  |  |  | 			if (type & ACPI_FORMAT_SIGN) { | 
					
						
							|  |  |  | 				number = (signed int)number; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 		pos = acpi_ut_format_number(pos, end, number, base, | 
					
						
							|  |  |  | 					    width, precision, type); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (size > 0) { | 
					
						
							|  |  |  | 		if (pos < end) { | 
					
						
							|  |  |  | 			*pos = '\0'; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			end[-1] = '\0'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (ACPI_PTR_DIFF(pos, string)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_snprintf | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  string              - String with boundary | 
					
						
							|  |  |  |  *              size                - Boundary of the string | 
					
						
							|  |  |  |  *              Format, ...         - Standard printf format | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  |  * RETURN:      Number of bytes actually written. | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Formatted output to a string. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	va_list args; | 
					
						
							|  |  |  | 	int length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(args, format); | 
					
						
							|  |  |  | 	length = acpi_ut_vsnprintf(string, size, format, args); | 
					
						
							|  |  |  | 	va_end(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef ACPI_APPLICATION
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_file_vprintf | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  file                - File descriptor | 
					
						
							|  |  |  |  *              format              - Standard printf format | 
					
						
							|  |  |  |  *              args                - Argument list | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  |  * RETURN:      Number of bytes actually written. | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Formatted output to a file using argument list pointer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	acpi_cpu_flags flags; | 
					
						
							|  |  |  | 	int length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	flags = acpi_os_acquire_lock(acpi_gbl_print_lock); | 
					
						
							|  |  |  | 	length = acpi_ut_vsnprintf(acpi_gbl_print_buffer, | 
					
						
							|  |  |  | 				   sizeof(acpi_gbl_print_buffer), format, args); | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  | 	(void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1); | 
					
						
							|  |  |  | 	acpi_os_release_lock(acpi_gbl_print_lock, flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FUNCTION:    acpi_ut_file_printf | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PARAMETERS:  file                - File descriptor | 
					
						
							|  |  |  |  *              Format, ...         - Standard printf format | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-07-08 10:08:13 +08:00
										 |  |  |  * RETURN:      Number of bytes actually written. | 
					
						
							| 
									
										
										
										
											2014-07-08 10:07:00 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * DESCRIPTION: Formatted output to a file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	va_list args; | 
					
						
							|  |  |  | 	int length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(args, format); | 
					
						
							|  |  |  | 	length = acpi_ut_file_vprintf(file, format, args); | 
					
						
							|  |  |  | 	va_end(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (length); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 |