Merge branch 'r6040-next'
[linux/fpc-iii.git] / drivers / acpi / acpica / utprint.c
blobdd084cf52502037b5f4eebf2f1b6b0fe38fcb859
1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #include <acpi/acpi.h>
45 #include "accommon.h"
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME("utprint")
50 #define ACPI_FORMAT_SIGN 0x01
51 #define ACPI_FORMAT_SIGN_PLUS 0x02
52 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
53 #define ACPI_FORMAT_ZERO 0x08
54 #define ACPI_FORMAT_LEFT 0x10
55 #define ACPI_FORMAT_UPPER 0x20
56 #define ACPI_FORMAT_PREFIX 0x40
57 /* Local prototypes */
58 static acpi_size
59 acpi_ut_bound_string_length(const char *string, acpi_size count);
61 static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
63 static char *acpi_ut_format_number(char *string,
64 char *end,
65 u64 number,
66 u8 base, s32 width, s32 precision, u8 type);
68 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
70 /*******************************************************************************
72 * FUNCTION: acpi_ut_bound_string_length
74 * PARAMETERS: string - String with boundary
75 * count - Boundary of the string
77 * RETURN: Length of the string. Less than or equal to Count.
79 * DESCRIPTION: Calculate the length of a string with boundary.
81 ******************************************************************************/
83 static acpi_size
84 acpi_ut_bound_string_length(const char *string, acpi_size count)
86 u32 length = 0;
88 while (*string && count) {
89 length++;
90 string++;
91 count--;
94 return (length);
97 /*******************************************************************************
99 * FUNCTION: acpi_ut_bound_string_output
101 * PARAMETERS: string - String with boundary
102 * end - Boundary of the string
103 * c - Character to be output to the string
105 * RETURN: Updated position for next valid character
107 * DESCRIPTION: Output a character into a string with boundary check.
109 ******************************************************************************/
111 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
114 if (string < end) {
115 *string = c;
118 ++string;
119 return (string);
122 /*******************************************************************************
124 * FUNCTION: acpi_ut_put_number
126 * PARAMETERS: string - Buffer to hold reverse-ordered string
127 * number - Integer to be converted
128 * base - Base of the integer
129 * upper - Whether or not using upper cased digits
131 * RETURN: Updated position for next valid character
133 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
134 * reversed ordered number without the trailing zero.
136 ******************************************************************************/
138 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
140 const char *digits;
141 u64 digit_index;
142 char *pos;
144 pos = string;
145 digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
147 if (number == 0) {
148 *(pos++) = '0';
149 } else {
150 while (number) {
151 (void)acpi_ut_divide(number, base, &number,
152 &digit_index);
153 *(pos++) = digits[digit_index];
157 /* *(Pos++) = '0'; */
158 return (pos);
161 /*******************************************************************************
163 * FUNCTION: acpi_ut_scan_number
165 * PARAMETERS: string - String buffer
166 * number_ptr - Where the number is returned
168 * RETURN: Updated position for next valid character
170 * DESCRIPTION: Scan a string for a decimal integer.
172 ******************************************************************************/
174 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
176 u64 number = 0;
178 while (isdigit((int)*string)) {
179 number *= 10;
180 number += *(string++) - '0';
183 *number_ptr = number;
184 return (string);
187 /*******************************************************************************
189 * FUNCTION: acpi_ut_print_number
191 * PARAMETERS: string - String buffer
192 * number - The number to be converted
194 * RETURN: Updated position for next valid character
196 * DESCRIPTION: Print a decimal integer into a string.
198 ******************************************************************************/
200 const char *acpi_ut_print_number(char *string, u64 number)
202 char ascii_string[20];
203 const char *pos1;
204 char *pos2;
206 pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
207 pos2 = string;
209 while (pos1 != ascii_string) {
210 *(pos2++) = *(--pos1);
213 *pos2 = 0;
214 return (string);
217 /*******************************************************************************
219 * FUNCTION: acpi_ut_format_number
221 * PARAMETERS: string - String buffer with boundary
222 * end - Boundary of the string
223 * number - The number to be converted
224 * base - Base of the integer
225 * width - Field width
226 * precision - Precision of the integer
227 * type - Special printing flags
229 * RETURN: Updated position for next valid character
231 * DESCRIPTION: Print an integer into a string with any base and any precision.
233 ******************************************************************************/
235 static char *acpi_ut_format_number(char *string,
236 char *end,
237 u64 number,
238 u8 base, s32 width, s32 precision, u8 type)
240 char *pos;
241 char sign;
242 char zero;
243 u8 need_prefix;
244 u8 upper;
245 s32 i;
246 char reversed_string[66];
248 /* Parameter validation */
250 if (base < 2 || base > 16) {
251 return (NULL);
254 if (type & ACPI_FORMAT_LEFT) {
255 type &= ~ACPI_FORMAT_ZERO;
258 need_prefix = ((type & ACPI_FORMAT_PREFIX)
259 && base != 10) ? TRUE : FALSE;
260 upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
261 zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
263 /* Calculate size according to sign and prefix */
265 sign = '\0';
266 if (type & ACPI_FORMAT_SIGN) {
267 if ((s64)number < 0) {
268 sign = '-';
269 number = -(s64)number;
270 width--;
271 } else if (type & ACPI_FORMAT_SIGN_PLUS) {
272 sign = '+';
273 width--;
274 } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
275 sign = ' ';
276 width--;
279 if (need_prefix) {
280 width--;
281 if (base == 16) {
282 width--;
286 /* Generate full string in reverse order */
288 pos = acpi_ut_put_number(reversed_string, number, base, upper);
289 i = ACPI_PTR_DIFF(pos, reversed_string);
291 /* Printing 100 using %2d gives "100", not "00" */
293 if (i > precision) {
294 precision = i;
297 width -= precision;
299 /* Output the string */
301 if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
302 while (--width >= 0) {
303 string = acpi_ut_bound_string_output(string, end, ' ');
306 if (sign) {
307 string = acpi_ut_bound_string_output(string, end, sign);
309 if (need_prefix) {
310 string = acpi_ut_bound_string_output(string, end, '0');
311 if (base == 16) {
312 string =
313 acpi_ut_bound_string_output(string, end,
314 upper ? 'X' : 'x');
317 if (!(type & ACPI_FORMAT_LEFT)) {
318 while (--width >= 0) {
319 string = acpi_ut_bound_string_output(string, end, zero);
323 while (i <= --precision) {
324 string = acpi_ut_bound_string_output(string, end, '0');
326 while (--i >= 0) {
327 string = acpi_ut_bound_string_output(string, end,
328 reversed_string[i]);
330 while (--width >= 0) {
331 string = acpi_ut_bound_string_output(string, end, ' ');
334 return (string);
337 /*******************************************************************************
339 * FUNCTION: acpi_ut_vsnprintf
341 * PARAMETERS: string - String with boundary
342 * size - Boundary of the string
343 * format - Standard printf format
344 * args - Argument list
346 * RETURN: Number of bytes actually written.
348 * DESCRIPTION: Formatted output to a string using argument list pointer.
350 ******************************************************************************/
353 acpi_ut_vsnprintf(char *string,
354 acpi_size size, const char *format, va_list args)
356 u8 base;
357 u8 type;
358 s32 width;
359 s32 precision;
360 char qualifier;
361 u64 number;
362 char *pos;
363 char *end;
364 char c;
365 const char *s;
366 const void *p;
367 s32 length;
368 int i;
370 pos = string;
371 end = string + size;
373 for (; *format; ++format) {
374 if (*format != '%') {
375 pos = acpi_ut_bound_string_output(pos, end, *format);
376 continue;
379 type = 0;
380 base = 10;
382 /* Process sign */
384 do {
385 ++format;
386 if (*format == '#') {
387 type |= ACPI_FORMAT_PREFIX;
388 } else if (*format == '0') {
389 type |= ACPI_FORMAT_ZERO;
390 } else if (*format == '+') {
391 type |= ACPI_FORMAT_SIGN_PLUS;
392 } else if (*format == ' ') {
393 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
394 } else if (*format == '-') {
395 type |= ACPI_FORMAT_LEFT;
396 } else {
397 break;
400 } while (1);
402 /* Process width */
404 width = -1;
405 if (isdigit((int)*format)) {
406 format = acpi_ut_scan_number(format, &number);
407 width = (s32)number;
408 } else if (*format == '*') {
409 ++format;
410 width = va_arg(args, int);
411 if (width < 0) {
412 width = -width;
413 type |= ACPI_FORMAT_LEFT;
417 /* Process precision */
419 precision = -1;
420 if (*format == '.') {
421 ++format;
422 if (isdigit((int)*format)) {
423 format = acpi_ut_scan_number(format, &number);
424 precision = (s32)number;
425 } else if (*format == '*') {
426 ++format;
427 precision = va_arg(args, int);
430 if (precision < 0) {
431 precision = 0;
435 /* Process qualifier */
437 qualifier = -1;
438 if (*format == 'h' || *format == 'l' || *format == 'L') {
439 qualifier = *format;
440 ++format;
442 if (qualifier == 'l' && *format == 'l') {
443 qualifier = 'L';
444 ++format;
448 switch (*format) {
449 case '%':
451 pos = acpi_ut_bound_string_output(pos, end, '%');
452 continue;
454 case 'c':
456 if (!(type & ACPI_FORMAT_LEFT)) {
457 while (--width > 0) {
458 pos =
459 acpi_ut_bound_string_output(pos,
460 end,
461 ' ');
465 c = (char)va_arg(args, int);
466 pos = acpi_ut_bound_string_output(pos, end, c);
468 while (--width > 0) {
469 pos =
470 acpi_ut_bound_string_output(pos, end, ' ');
472 continue;
474 case 's':
476 s = va_arg(args, char *);
477 if (!s) {
478 s = "<NULL>";
480 length = acpi_ut_bound_string_length(s, precision);
481 if (!(type & ACPI_FORMAT_LEFT)) {
482 while (length < width--) {
483 pos =
484 acpi_ut_bound_string_output(pos,
485 end,
486 ' ');
490 for (i = 0; i < length; ++i) {
491 pos = acpi_ut_bound_string_output(pos, end, *s);
492 ++s;
495 while (length < width--) {
496 pos =
497 acpi_ut_bound_string_output(pos, end, ' ');
499 continue;
501 case 'o':
503 base = 8;
504 break;
506 case 'X':
508 type |= ACPI_FORMAT_UPPER;
510 case 'x':
512 base = 16;
513 break;
515 case 'd':
516 case 'i':
518 type |= ACPI_FORMAT_SIGN;
520 case 'u':
522 break;
524 case 'p':
526 if (width == -1) {
527 width = 2 * sizeof(void *);
528 type |= ACPI_FORMAT_ZERO;
531 p = va_arg(args, void *);
532 pos =
533 acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
534 16, width, precision, type);
535 continue;
537 default:
539 pos = acpi_ut_bound_string_output(pos, end, '%');
540 if (*format) {
541 pos =
542 acpi_ut_bound_string_output(pos, end,
543 *format);
544 } else {
545 --format;
547 continue;
550 if (qualifier == 'L') {
551 number = va_arg(args, u64);
552 if (type & ACPI_FORMAT_SIGN) {
553 number = (s64)number;
555 } else if (qualifier == 'l') {
556 number = va_arg(args, unsigned long);
557 if (type & ACPI_FORMAT_SIGN) {
558 number = (s32)number;
560 } else if (qualifier == 'h') {
561 number = (u16)va_arg(args, int);
562 if (type & ACPI_FORMAT_SIGN) {
563 number = (s16)number;
565 } else {
566 number = va_arg(args, unsigned int);
567 if (type & ACPI_FORMAT_SIGN) {
568 number = (signed int)number;
572 pos = acpi_ut_format_number(pos, end, number, base,
573 width, precision, type);
576 if (size > 0) {
577 if (pos < end) {
578 *pos = '\0';
579 } else {
580 end[-1] = '\0';
584 return (ACPI_PTR_DIFF(pos, string));
587 /*******************************************************************************
589 * FUNCTION: acpi_ut_snprintf
591 * PARAMETERS: string - String with boundary
592 * size - Boundary of the string
593 * Format, ... - Standard printf format
595 * RETURN: Number of bytes actually written.
597 * DESCRIPTION: Formatted output to a string.
599 ******************************************************************************/
601 int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
603 va_list args;
604 int length;
606 va_start(args, format);
607 length = acpi_ut_vsnprintf(string, size, format, args);
608 va_end(args);
610 return (length);
613 #ifdef ACPI_APPLICATION
614 /*******************************************************************************
616 * FUNCTION: acpi_ut_file_vprintf
618 * PARAMETERS: file - File descriptor
619 * format - Standard printf format
620 * args - Argument list
622 * RETURN: Number of bytes actually written.
624 * DESCRIPTION: Formatted output to a file using argument list pointer.
626 ******************************************************************************/
628 int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
630 acpi_cpu_flags flags;
631 int length;
633 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
634 length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
635 sizeof(acpi_gbl_print_buffer), format, args);
637 (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
638 acpi_os_release_lock(acpi_gbl_print_lock, flags);
640 return (length);
643 /*******************************************************************************
645 * FUNCTION: acpi_ut_file_printf
647 * PARAMETERS: file - File descriptor
648 * Format, ... - Standard printf format
650 * RETURN: Number of bytes actually written.
652 * DESCRIPTION: Formatted output to a file.
654 ******************************************************************************/
656 int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
658 va_list args;
659 int length;
661 va_start(args, format);
662 length = acpi_ut_file_vprintf(file, format, args);
663 va_end(args);
665 return (length);
667 #endif