mm/hmm.c: remove superfluous RCU protection around radix tree lookup
[linux/fpc-iii.git] / drivers / acpi / acpica / utprint.c
blob35ffd8d51c6541a3034764d2015ec1c4d538a4a3
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: utprint - Formatted printing routines
6 * Copyright (C) 2000 - 2018, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
11 #include "accommon.h"
13 #define _COMPONENT ACPI_UTILITIES
14 ACPI_MODULE_NAME("utprint")
16 #define ACPI_FORMAT_SIGN 0x01
17 #define ACPI_FORMAT_SIGN_PLUS 0x02
18 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
19 #define ACPI_FORMAT_ZERO 0x08
20 #define ACPI_FORMAT_LEFT 0x10
21 #define ACPI_FORMAT_UPPER 0x20
22 #define ACPI_FORMAT_PREFIX 0x40
23 /* Local prototypes */
24 static acpi_size
25 acpi_ut_bound_string_length(const char *string, acpi_size count);
27 static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
29 static char *acpi_ut_format_number(char *string,
30 char *end,
31 u64 number,
32 u8 base, s32 width, s32 precision, u8 type);
34 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
36 /*******************************************************************************
38 * FUNCTION: acpi_ut_bound_string_length
40 * PARAMETERS: string - String with boundary
41 * count - Boundary of the string
43 * RETURN: Length of the string. Less than or equal to Count.
45 * DESCRIPTION: Calculate the length of a string with boundary.
47 ******************************************************************************/
49 static acpi_size
50 acpi_ut_bound_string_length(const char *string, acpi_size count)
52 u32 length = 0;
54 while (*string && count) {
55 length++;
56 string++;
57 count--;
60 return (length);
63 /*******************************************************************************
65 * FUNCTION: acpi_ut_bound_string_output
67 * PARAMETERS: string - String with boundary
68 * end - Boundary of the string
69 * c - Character to be output to the string
71 * RETURN: Updated position for next valid character
73 * DESCRIPTION: Output a character into a string with boundary check.
75 ******************************************************************************/
77 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
80 if (string < end) {
81 *string = c;
84 ++string;
85 return (string);
88 /*******************************************************************************
90 * FUNCTION: acpi_ut_put_number
92 * PARAMETERS: string - Buffer to hold reverse-ordered string
93 * number - Integer to be converted
94 * base - Base of the integer
95 * upper - Whether or not using upper cased digits
97 * RETURN: Updated position for next valid character
99 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
100 * reversed ordered number without the trailing zero.
102 ******************************************************************************/
104 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
106 const char *digits;
107 u64 digit_index;
108 char *pos;
110 pos = string;
111 digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
113 if (number == 0) {
114 *(pos++) = '0';
115 } else {
116 while (number) {
117 (void)acpi_ut_divide(number, base, &number,
118 &digit_index);
119 *(pos++) = digits[digit_index];
123 /* *(Pos++) = '0'; */
124 return (pos);
127 /*******************************************************************************
129 * FUNCTION: acpi_ut_scan_number
131 * PARAMETERS: string - String buffer
132 * number_ptr - Where the number is returned
134 * RETURN: Updated position for next valid character
136 * DESCRIPTION: Scan a string for a decimal integer.
138 ******************************************************************************/
140 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
142 u64 number = 0;
144 while (isdigit((int)*string)) {
145 acpi_ut_short_multiply(number, 10, &number);
146 number += *(string++) - '0';
149 *number_ptr = number;
150 return (string);
153 /*******************************************************************************
155 * FUNCTION: acpi_ut_print_number
157 * PARAMETERS: string - String buffer
158 * number - The number to be converted
160 * RETURN: Updated position for next valid character
162 * DESCRIPTION: Print a decimal integer into a string.
164 ******************************************************************************/
166 const char *acpi_ut_print_number(char *string, u64 number)
168 char ascii_string[20];
169 const char *pos1;
170 char *pos2;
172 pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
173 pos2 = string;
175 while (pos1 != ascii_string) {
176 *(pos2++) = *(--pos1);
179 *pos2 = 0;
180 return (string);
183 /*******************************************************************************
185 * FUNCTION: acpi_ut_format_number
187 * PARAMETERS: string - String buffer with boundary
188 * end - Boundary of the string
189 * number - The number to be converted
190 * base - Base of the integer
191 * width - Field width
192 * precision - Precision of the integer
193 * type - Special printing flags
195 * RETURN: Updated position for next valid character
197 * DESCRIPTION: Print an integer into a string with any base and any precision.
199 ******************************************************************************/
201 static char *acpi_ut_format_number(char *string,
202 char *end,
203 u64 number,
204 u8 base, s32 width, s32 precision, u8 type)
206 char *pos;
207 char sign;
208 char zero;
209 u8 need_prefix;
210 u8 upper;
211 s32 i;
212 char reversed_string[66];
214 /* Parameter validation */
216 if (base < 2 || base > 16) {
217 return (NULL);
220 if (type & ACPI_FORMAT_LEFT) {
221 type &= ~ACPI_FORMAT_ZERO;
224 need_prefix = ((type & ACPI_FORMAT_PREFIX)
225 && base != 10) ? TRUE : FALSE;
226 upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
227 zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
229 /* Calculate size according to sign and prefix */
231 sign = '\0';
232 if (type & ACPI_FORMAT_SIGN) {
233 if ((s64)number < 0) {
234 sign = '-';
235 number = -(s64)number;
236 width--;
237 } else if (type & ACPI_FORMAT_SIGN_PLUS) {
238 sign = '+';
239 width--;
240 } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
241 sign = ' ';
242 width--;
245 if (need_prefix) {
246 width--;
247 if (base == 16) {
248 width--;
252 /* Generate full string in reverse order */
254 pos = acpi_ut_put_number(reversed_string, number, base, upper);
255 i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
257 /* Printing 100 using %2d gives "100", not "00" */
259 if (i > precision) {
260 precision = i;
263 width -= precision;
265 /* Output the string */
267 if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
268 while (--width >= 0) {
269 string = acpi_ut_bound_string_output(string, end, ' ');
272 if (sign) {
273 string = acpi_ut_bound_string_output(string, end, sign);
275 if (need_prefix) {
276 string = acpi_ut_bound_string_output(string, end, '0');
277 if (base == 16) {
278 string =
279 acpi_ut_bound_string_output(string, end,
280 upper ? 'X' : 'x');
283 if (!(type & ACPI_FORMAT_LEFT)) {
284 while (--width >= 0) {
285 string = acpi_ut_bound_string_output(string, end, zero);
289 while (i <= --precision) {
290 string = acpi_ut_bound_string_output(string, end, '0');
292 while (--i >= 0) {
293 string = acpi_ut_bound_string_output(string, end,
294 reversed_string[i]);
296 while (--width >= 0) {
297 string = acpi_ut_bound_string_output(string, end, ' ');
300 return (string);
303 /*******************************************************************************
305 * FUNCTION: vsnprintf
307 * PARAMETERS: string - String with boundary
308 * size - Boundary of the string
309 * format - Standard printf format
310 * args - Argument list
312 * RETURN: Number of bytes actually written.
314 * DESCRIPTION: Formatted output to a string using argument list pointer.
316 ******************************************************************************/
318 int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
320 u8 base;
321 u8 type;
322 s32 width;
323 s32 precision;
324 char qualifier;
325 u64 number;
326 char *pos;
327 char *end;
328 char c;
329 const char *s;
330 const void *p;
331 s32 length;
332 int i;
334 pos = string;
335 end = string + size;
337 for (; *format; ++format) {
338 if (*format != '%') {
339 pos = acpi_ut_bound_string_output(pos, end, *format);
340 continue;
343 type = 0;
344 base = 10;
346 /* Process sign */
348 do {
349 ++format;
350 if (*format == '#') {
351 type |= ACPI_FORMAT_PREFIX;
352 } else if (*format == '0') {
353 type |= ACPI_FORMAT_ZERO;
354 } else if (*format == '+') {
355 type |= ACPI_FORMAT_SIGN_PLUS;
356 } else if (*format == ' ') {
357 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
358 } else if (*format == '-') {
359 type |= ACPI_FORMAT_LEFT;
360 } else {
361 break;
364 } while (1);
366 /* Process width */
368 width = -1;
369 if (isdigit((int)*format)) {
370 format = acpi_ut_scan_number(format, &number);
371 width = (s32)number;
372 } else if (*format == '*') {
373 ++format;
374 width = va_arg(args, int);
375 if (width < 0) {
376 width = -width;
377 type |= ACPI_FORMAT_LEFT;
381 /* Process precision */
383 precision = -1;
384 if (*format == '.') {
385 ++format;
386 if (isdigit((int)*format)) {
387 format = acpi_ut_scan_number(format, &number);
388 precision = (s32)number;
389 } else if (*format == '*') {
390 ++format;
391 precision = va_arg(args, int);
394 if (precision < 0) {
395 precision = 0;
399 /* Process qualifier */
401 qualifier = -1;
402 if (*format == 'h' || *format == 'l' || *format == 'L') {
403 qualifier = *format;
404 ++format;
406 if (qualifier == 'l' && *format == 'l') {
407 qualifier = 'L';
408 ++format;
412 switch (*format) {
413 case '%':
415 pos = acpi_ut_bound_string_output(pos, end, '%');
416 continue;
418 case 'c':
420 if (!(type & ACPI_FORMAT_LEFT)) {
421 while (--width > 0) {
422 pos =
423 acpi_ut_bound_string_output(pos,
424 end,
425 ' ');
429 c = (char)va_arg(args, int);
430 pos = acpi_ut_bound_string_output(pos, end, c);
432 while (--width > 0) {
433 pos =
434 acpi_ut_bound_string_output(pos, end, ' ');
436 continue;
438 case 's':
440 s = va_arg(args, char *);
441 if (!s) {
442 s = "<NULL>";
444 length = (s32)acpi_ut_bound_string_length(s, precision);
445 if (!(type & ACPI_FORMAT_LEFT)) {
446 while (length < width--) {
447 pos =
448 acpi_ut_bound_string_output(pos,
449 end,
450 ' ');
454 for (i = 0; i < length; ++i) {
455 pos = acpi_ut_bound_string_output(pos, end, *s);
456 ++s;
459 while (length < width--) {
460 pos =
461 acpi_ut_bound_string_output(pos, end, ' ');
463 continue;
465 case 'o':
467 base = 8;
468 break;
470 case 'X':
472 type |= ACPI_FORMAT_UPPER;
474 case 'x':
476 base = 16;
477 break;
479 case 'd':
480 case 'i':
482 type |= ACPI_FORMAT_SIGN;
484 case 'u':
486 break;
488 case 'p':
490 if (width == -1) {
491 width = 2 * sizeof(void *);
492 type |= ACPI_FORMAT_ZERO;
495 p = va_arg(args, void *);
496 pos =
497 acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
498 16, width, precision, type);
499 continue;
501 default:
503 pos = acpi_ut_bound_string_output(pos, end, '%');
504 if (*format) {
505 pos =
506 acpi_ut_bound_string_output(pos, end,
507 *format);
508 } else {
509 --format;
511 continue;
514 if (qualifier == 'L') {
515 number = va_arg(args, u64);
516 if (type & ACPI_FORMAT_SIGN) {
517 number = (s64)number;
519 } else if (qualifier == 'l') {
520 number = va_arg(args, unsigned long);
521 if (type & ACPI_FORMAT_SIGN) {
522 number = (s32)number;
524 } else if (qualifier == 'h') {
525 number = (u16)va_arg(args, int);
526 if (type & ACPI_FORMAT_SIGN) {
527 number = (s16)number;
529 } else {
530 number = va_arg(args, unsigned int);
531 if (type & ACPI_FORMAT_SIGN) {
532 number = (signed int)number;
536 pos = acpi_ut_format_number(pos, end, number, base,
537 width, precision, type);
540 if (size > 0) {
541 if (pos < end) {
542 *pos = '\0';
543 } else {
544 end[-1] = '\0';
548 return ((int)ACPI_PTR_DIFF(pos, string));
551 /*******************************************************************************
553 * FUNCTION: snprintf
555 * PARAMETERS: string - String with boundary
556 * size - Boundary of the string
557 * Format, ... - Standard printf format
559 * RETURN: Number of bytes actually written.
561 * DESCRIPTION: Formatted output to a string.
563 ******************************************************************************/
565 int snprintf(char *string, acpi_size size, const char *format, ...)
567 va_list args;
568 int length;
570 va_start(args, format);
571 length = vsnprintf(string, size, format, args);
572 va_end(args);
574 return (length);
577 /*******************************************************************************
579 * FUNCTION: sprintf
581 * PARAMETERS: string - String with boundary
582 * Format, ... - Standard printf format
584 * RETURN: Number of bytes actually written.
586 * DESCRIPTION: Formatted output to a string.
588 ******************************************************************************/
590 int sprintf(char *string, const char *format, ...)
592 va_list args;
593 int length;
595 va_start(args, format);
596 length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
597 va_end(args);
599 return (length);
602 #ifdef ACPI_APPLICATION
603 /*******************************************************************************
605 * FUNCTION: vprintf
607 * PARAMETERS: format - Standard printf format
608 * args - Argument list
610 * RETURN: Number of bytes actually written.
612 * DESCRIPTION: Formatted output to stdout using argument list pointer.
614 ******************************************************************************/
616 int vprintf(const char *format, va_list args)
618 acpi_cpu_flags flags;
619 int length;
621 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
622 length = vsnprintf(acpi_gbl_print_buffer,
623 sizeof(acpi_gbl_print_buffer), format, args);
625 (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
626 acpi_os_release_lock(acpi_gbl_print_lock, flags);
628 return (length);
631 /*******************************************************************************
633 * FUNCTION: printf
635 * PARAMETERS: Format, ... - Standard printf format
637 * RETURN: Number of bytes actually written.
639 * DESCRIPTION: Formatted output to stdout.
641 ******************************************************************************/
643 int printf(const char *format, ...)
645 va_list args;
646 int length;
648 va_start(args, format);
649 length = vprintf(format, args);
650 va_end(args);
652 return (length);
655 /*******************************************************************************
657 * FUNCTION: vfprintf
659 * PARAMETERS: file - File descriptor
660 * format - Standard printf format
661 * args - Argument list
663 * RETURN: Number of bytes actually written.
665 * DESCRIPTION: Formatted output to a file using argument list pointer.
667 ******************************************************************************/
669 int vfprintf(FILE * file, const char *format, va_list args)
671 acpi_cpu_flags flags;
672 int length;
674 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
675 length = vsnprintf(acpi_gbl_print_buffer,
676 sizeof(acpi_gbl_print_buffer), format, args);
678 (void)fwrite(acpi_gbl_print_buffer, length, 1, file);
679 acpi_os_release_lock(acpi_gbl_print_lock, flags);
681 return (length);
684 /*******************************************************************************
686 * FUNCTION: fprintf
688 * PARAMETERS: file - File descriptor
689 * Format, ... - Standard printf format
691 * RETURN: Number of bytes actually written.
693 * DESCRIPTION: Formatted output to a file.
695 ******************************************************************************/
697 int fprintf(FILE * file, const char *format, ...)
699 va_list args;
700 int length;
702 va_start(args, format);
703 length = vfprintf(file, format, args);
704 va_end(args);
706 return (length);
708 #endif