mm/zsmalloc: allocate exactly size of struct zs_pool
[linux/fpc-iii.git] / drivers / acpi / acpica / utprint.c
blob0ce3f5a0dd670945208d9e3b949ff8640d541235
1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2014, 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 /* Module globals */
72 static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef";
73 static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF";
75 /*******************************************************************************
77 * FUNCTION: acpi_ut_bound_string_length
79 * PARAMETERS: string - String with boundary
80 * count - Boundary of the string
82 * RETURN: Length of the string. Less than or equal to Count.
84 * DESCRIPTION: Calculate the length of a string with boundary.
86 ******************************************************************************/
88 static acpi_size
89 acpi_ut_bound_string_length(const char *string, acpi_size count)
91 u32 length = 0;
93 while (*string && count) {
94 length++;
95 string++;
96 count--;
99 return (length);
102 /*******************************************************************************
104 * FUNCTION: acpi_ut_bound_string_output
106 * PARAMETERS: string - String with boundary
107 * end - Boundary of the string
108 * c - Character to be output to the string
110 * RETURN: Updated position for next valid character
112 * DESCRIPTION: Output a character into a string with boundary check.
114 ******************************************************************************/
116 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
119 if (string < end) {
120 *string = c;
123 ++string;
124 return (string);
127 /*******************************************************************************
129 * FUNCTION: acpi_ut_put_number
131 * PARAMETERS: string - Buffer to hold reverse-ordered string
132 * number - Integer to be converted
133 * base - Base of the integer
134 * upper - Whether or not using upper cased digits
136 * RETURN: Updated position for next valid character
138 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
139 * reversed ordered number without the trailing zero.
141 ******************************************************************************/
143 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
145 const char *digits;
146 u64 digit_index;
147 char *pos;
149 pos = string;
150 digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
152 if (number == 0) {
153 *(pos++) = '0';
154 } else {
155 while (number) {
156 (void)acpi_ut_divide(number, base, &number,
157 &digit_index);
158 *(pos++) = digits[digit_index];
162 /* *(Pos++) = '0'; */
163 return (pos);
166 /*******************************************************************************
168 * FUNCTION: acpi_ut_scan_number
170 * PARAMETERS: string - String buffer
171 * number_ptr - Where the number is returned
173 * RETURN: Updated position for next valid character
175 * DESCRIPTION: Scan a string for a decimal integer.
177 ******************************************************************************/
179 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
181 u64 number = 0;
183 while (ACPI_IS_DIGIT(*string)) {
184 number *= 10;
185 number += *(string++) - '0';
188 *number_ptr = number;
189 return (string);
192 /*******************************************************************************
194 * FUNCTION: acpi_ut_print_number
196 * PARAMETERS: string - String buffer
197 * number - The number to be converted
199 * RETURN: Updated position for next valid character
201 * DESCRIPTION: Print a decimal integer into a string.
203 ******************************************************************************/
205 const char *acpi_ut_print_number(char *string, u64 number)
207 char ascii_string[20];
208 const char *pos1;
209 char *pos2;
211 pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
212 pos2 = string;
214 while (pos1 != ascii_string) {
215 *(pos2++) = *(--pos1);
218 *pos2 = 0;
219 return (string);
222 /*******************************************************************************
224 * FUNCTION: acpi_ut_format_number
226 * PARAMETERS: string - String buffer with boundary
227 * end - Boundary of the string
228 * number - The number to be converted
229 * base - Base of the integer
230 * width - Field width
231 * precision - Precision of the integer
232 * type - Special printing flags
234 * RETURN: Updated position for next valid character
236 * DESCRIPTION: Print an integer into a string with any base and any precision.
238 ******************************************************************************/
240 static char *acpi_ut_format_number(char *string,
241 char *end,
242 u64 number,
243 u8 base, s32 width, s32 precision, u8 type)
245 char *pos;
246 char sign;
247 char zero;
248 u8 need_prefix;
249 u8 upper;
250 s32 i;
251 char reversed_string[66];
253 /* Parameter validation */
255 if (base < 2 || base > 16) {
256 return (NULL);
259 if (type & ACPI_FORMAT_LEFT) {
260 type &= ~ACPI_FORMAT_ZERO;
263 need_prefix = ((type & ACPI_FORMAT_PREFIX)
264 && base != 10) ? TRUE : FALSE;
265 upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
266 zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
268 /* Calculate size according to sign and prefix */
270 sign = '\0';
271 if (type & ACPI_FORMAT_SIGN) {
272 if ((s64) number < 0) {
273 sign = '-';
274 number = -(s64) number;
275 width--;
276 } else if (type & ACPI_FORMAT_SIGN_PLUS) {
277 sign = '+';
278 width--;
279 } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
280 sign = ' ';
281 width--;
284 if (need_prefix) {
285 width--;
286 if (base == 16) {
287 width--;
291 /* Generate full string in reverse order */
293 pos = acpi_ut_put_number(reversed_string, number, base, upper);
294 i = ACPI_PTR_DIFF(pos, reversed_string);
296 /* Printing 100 using %2d gives "100", not "00" */
298 if (i > precision) {
299 precision = i;
302 width -= precision;
304 /* Output the string */
306 if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
307 while (--width >= 0) {
308 string = acpi_ut_bound_string_output(string, end, ' ');
311 if (sign) {
312 string = acpi_ut_bound_string_output(string, end, sign);
314 if (need_prefix) {
315 string = acpi_ut_bound_string_output(string, end, '0');
316 if (base == 16) {
317 string = acpi_ut_bound_string_output(string, end,
318 upper ? 'X' : 'x');
321 if (!(type & ACPI_FORMAT_LEFT)) {
322 while (--width >= 0) {
323 string = acpi_ut_bound_string_output(string, end, zero);
327 while (i <= --precision) {
328 string = acpi_ut_bound_string_output(string, end, '0');
330 while (--i >= 0) {
331 string = acpi_ut_bound_string_output(string, end,
332 reversed_string[i]);
334 while (--width >= 0) {
335 string = acpi_ut_bound_string_output(string, end, ' ');
338 return (string);
341 /*******************************************************************************
343 * FUNCTION: acpi_ut_vsnprintf
345 * PARAMETERS: string - String with boundary
346 * size - Boundary of the string
347 * format - Standard printf format
348 * args - Argument list
350 * RETURN: Number of bytes actually written.
352 * DESCRIPTION: Formatted output to a string using argument list pointer.
354 ******************************************************************************/
357 acpi_ut_vsnprintf(char *string,
358 acpi_size size, const char *format, va_list args)
360 u8 base = 10;
361 u8 type = 0;
362 s32 width = -1;
363 s32 precision = -1;
364 char qualifier = 0;
365 u64 number;
366 char *pos;
367 char *end;
368 char c;
369 const char *s;
370 const void *p;
371 s32 length;
372 int i;
374 pos = string;
375 end = string + size;
377 for (; *format; ++format) {
378 if (*format != '%') {
379 pos = acpi_ut_bound_string_output(pos, end, *format);
380 continue;
383 /* Process sign */
385 do {
386 ++format;
387 if (*format == '#') {
388 type |= ACPI_FORMAT_PREFIX;
389 } else if (*format == '0') {
390 type |= ACPI_FORMAT_ZERO;
391 } else if (*format == '+') {
392 type |= ACPI_FORMAT_SIGN_PLUS;
393 } else if (*format == ' ') {
394 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
395 } else if (*format == '-') {
396 type |= ACPI_FORMAT_LEFT;
397 } else {
398 break;
400 } while (1);
402 /* Process width */
404 width = -1;
405 if (ACPI_IS_DIGIT(*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 (ACPI_IS_DIGIT(*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);
429 if (precision < 0) {
430 precision = 0;
434 /* Process qualifier */
436 qualifier = -1;
437 if (*format == 'h' || *format == 'l' || *format == 'L') {
438 qualifier = *format;
439 ++format;
441 if (qualifier == 'l' && *format == 'l') {
442 qualifier = 'L';
443 ++format;
447 switch (*format) {
448 case '%':
450 pos = acpi_ut_bound_string_output(pos, end, '%');
451 continue;
453 case 'c':
455 if (!(type & ACPI_FORMAT_LEFT)) {
456 while (--width > 0) {
457 pos =
458 acpi_ut_bound_string_output(pos,
459 end,
460 ' ');
464 c = (char)va_arg(args, int);
465 pos = acpi_ut_bound_string_output(pos, end, c);
467 while (--width > 0) {
468 pos =
469 acpi_ut_bound_string_output(pos, end, ' ');
471 continue;
473 case 's':
475 s = va_arg(args, char *);
476 if (!s) {
477 s = "<NULL>";
479 length = acpi_ut_bound_string_length(s, precision);
480 if (!(type & ACPI_FORMAT_LEFT)) {
481 while (length < width--) {
482 pos =
483 acpi_ut_bound_string_output(pos,
484 end,
485 ' ');
488 for (i = 0; i < length; ++i) {
489 pos = acpi_ut_bound_string_output(pos, end, *s);
490 ++s;
492 while (length < width--) {
493 pos =
494 acpi_ut_bound_string_output(pos, end, ' ');
496 continue;
498 case 'o':
500 base = 8;
501 break;
503 case 'X':
505 type |= ACPI_FORMAT_UPPER;
507 case 'x':
509 base = 16;
510 break;
512 case 'd':
513 case 'i':
515 type |= ACPI_FORMAT_SIGN;
517 case 'u':
519 break;
521 case 'p':
523 if (width == -1) {
524 width = 2 * sizeof(void *);
525 type |= ACPI_FORMAT_ZERO;
528 p = va_arg(args, void *);
529 pos = acpi_ut_format_number(pos, end,
530 ACPI_TO_INTEGER(p), 16,
531 width, precision, type);
532 continue;
534 default:
536 pos = acpi_ut_bound_string_output(pos, end, '%');
537 if (*format) {
538 pos =
539 acpi_ut_bound_string_output(pos, end,
540 *format);
541 } else {
542 --format;
544 continue;
547 if (qualifier == 'L') {
548 number = va_arg(args, u64);
549 if (type & ACPI_FORMAT_SIGN) {
550 number = (s64) number;
552 } else if (qualifier == 'l') {
553 number = va_arg(args, unsigned long);
554 if (type & ACPI_FORMAT_SIGN) {
555 number = (s32) number;
557 } else if (qualifier == 'h') {
558 number = (u16)va_arg(args, int);
559 if (type & ACPI_FORMAT_SIGN) {
560 number = (s16) number;
562 } else {
563 number = va_arg(args, unsigned int);
564 if (type & ACPI_FORMAT_SIGN) {
565 number = (signed int)number;
569 pos = acpi_ut_format_number(pos, end, number, base,
570 width, precision, type);
573 if (size > 0) {
574 if (pos < end) {
575 *pos = '\0';
576 } else {
577 end[-1] = '\0';
581 return (ACPI_PTR_DIFF(pos, string));
584 /*******************************************************************************
586 * FUNCTION: acpi_ut_snprintf
588 * PARAMETERS: string - String with boundary
589 * size - Boundary of the string
590 * Format, ... - Standard printf format
592 * RETURN: Number of bytes actually written.
594 * DESCRIPTION: Formatted output to a string.
596 ******************************************************************************/
598 int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
600 va_list args;
601 int length;
603 va_start(args, format);
604 length = acpi_ut_vsnprintf(string, size, format, args);
605 va_end(args);
607 return (length);
610 #ifdef ACPI_APPLICATION
611 /*******************************************************************************
613 * FUNCTION: acpi_ut_file_vprintf
615 * PARAMETERS: file - File descriptor
616 * format - Standard printf format
617 * args - Argument list
619 * RETURN: Number of bytes actually written.
621 * DESCRIPTION: Formatted output to a file using argument list pointer.
623 ******************************************************************************/
625 int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
627 acpi_cpu_flags flags;
628 int length;
630 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
631 length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
632 sizeof(acpi_gbl_print_buffer), format, args);
634 (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
635 acpi_os_release_lock(acpi_gbl_print_lock, flags);
637 return (length);
640 /*******************************************************************************
642 * FUNCTION: acpi_ut_file_printf
644 * PARAMETERS: file - File descriptor
645 * Format, ... - Standard printf format
647 * RETURN: Number of bytes actually written.
649 * DESCRIPTION: Formatted output to a file.
651 ******************************************************************************/
653 int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
655 va_list args;
656 int length;
658 va_start(args, format);
659 length = acpi_ut_file_vprintf(file, format, args);
660 va_end(args);
662 return (length);
664 #endif