Merge tag 'phy-fixes-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux...
[linux-2.6-microblaze.git] / drivers / acpi / acpica / utprint.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: utprint - Formatted printing routines
5  *
6  * Copyright (C) 2000 - 2021, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12
13 #define _COMPONENT          ACPI_UTILITIES
14 ACPI_MODULE_NAME("utprint")
15
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);
26
27 static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
28
29 static char *acpi_ut_format_number(char *string,
30                                    char *end,
31                                    u64 number,
32                                    u8 base, s32 width, s32 precision, u8 type);
33
34 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
35
36 /*******************************************************************************
37  *
38  * FUNCTION:    acpi_ut_bound_string_length
39  *
40  * PARAMETERS:  string              - String with boundary
41  *              count               - Boundary of the string
42  *
43  * RETURN:      Length of the string. Less than or equal to Count.
44  *
45  * DESCRIPTION: Calculate the length of a string with boundary.
46  *
47  ******************************************************************************/
48
49 static acpi_size
50 acpi_ut_bound_string_length(const char *string, acpi_size count)
51 {
52         u32 length = 0;
53
54         while (*string && count) {
55                 length++;
56                 string++;
57                 count--;
58         }
59
60         return (length);
61 }
62
63 /*******************************************************************************
64  *
65  * FUNCTION:    acpi_ut_bound_string_output
66  *
67  * PARAMETERS:  string              - String with boundary
68  *              end                 - Boundary of the string
69  *              c                   - Character to be output to the string
70  *
71  * RETURN:      Updated position for next valid character
72  *
73  * DESCRIPTION: Output a character into a string with boundary check.
74  *
75  ******************************************************************************/
76
77 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
78 {
79
80         if (string < end) {
81                 *string = c;
82         }
83
84         ++string;
85         return (string);
86 }
87
88 /*******************************************************************************
89  *
90  * FUNCTION:    acpi_ut_put_number
91  *
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
96  *
97  * RETURN:      Updated position for next valid character
98  *
99  * DESCRIPTION: Convert an integer into a string, note that, the string holds a
100  *              reversed ordered number without the trailing zero.
101  *
102  ******************************************************************************/
103
104 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
105 {
106         const char *digits;
107         u64 digit_index;
108         char *pos;
109
110         pos = string;
111         digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
112
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];
120                 }
121         }
122
123         /* *(Pos++) = '0'; */
124         return (pos);
125 }
126
127 /*******************************************************************************
128  *
129  * FUNCTION:    acpi_ut_scan_number
130  *
131  * PARAMETERS:  string              - String buffer
132  *              number_ptr          - Where the number is returned
133  *
134  * RETURN:      Updated position for next valid character
135  *
136  * DESCRIPTION: Scan a string for a decimal integer.
137  *
138  ******************************************************************************/
139
140 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
141 {
142         u64 number = 0;
143
144         while (isdigit((int)*string)) {
145                 acpi_ut_short_multiply(number, 10, &number);
146                 number += *(string++) - '0';
147         }
148
149         *number_ptr = number;
150         return (string);
151 }
152
153 /*******************************************************************************
154  *
155  * FUNCTION:    acpi_ut_print_number
156  *
157  * PARAMETERS:  string              - String buffer
158  *              number              - The number to be converted
159  *
160  * RETURN:      Updated position for next valid character
161  *
162  * DESCRIPTION: Print a decimal integer into a string.
163  *
164  ******************************************************************************/
165
166 const char *acpi_ut_print_number(char *string, u64 number)
167 {
168         char ascii_string[20];
169         const char *pos1;
170         char *pos2;
171
172         pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
173         pos2 = string;
174
175         while (pos1 != ascii_string) {
176                 *(pos2++) = *(--pos1);
177         }
178
179         *pos2 = 0;
180         return (string);
181 }
182
183 /*******************************************************************************
184  *
185  * FUNCTION:    acpi_ut_format_number
186  *
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
194  *
195  * RETURN:      Updated position for next valid character
196  *
197  * DESCRIPTION: Print an integer into a string with any base and any precision.
198  *
199  ******************************************************************************/
200
201 static char *acpi_ut_format_number(char *string,
202                                    char *end,
203                                    u64 number,
204                                    u8 base, s32 width, s32 precision, u8 type)
205 {
206         char *pos;
207         char sign;
208         char zero;
209         u8 need_prefix;
210         u8 upper;
211         s32 i;
212         char reversed_string[66];
213
214         /* Parameter validation */
215
216         if (base < 2 || base > 16) {
217                 return (NULL);
218         }
219
220         if (type & ACPI_FORMAT_LEFT) {
221                 type &= ~ACPI_FORMAT_ZERO;
222         }
223
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' : ' ';
228
229         /* Calculate size according to sign and prefix */
230
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--;
243                 }
244         }
245         if (need_prefix) {
246                 width--;
247                 if (base == 16) {
248                         width--;
249                 }
250         }
251
252         /* Generate full string in reverse order */
253
254         pos = acpi_ut_put_number(reversed_string, number, base, upper);
255         i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
256
257         /* Printing 100 using %2d gives "100", not "00" */
258
259         if (i > precision) {
260                 precision = i;
261         }
262
263         width -= precision;
264
265         /* Output the string */
266
267         if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
268                 while (--width >= 0) {
269                         string = acpi_ut_bound_string_output(string, end, ' ');
270                 }
271         }
272         if (sign) {
273                 string = acpi_ut_bound_string_output(string, end, sign);
274         }
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');
281                 }
282         }
283         if (!(type & ACPI_FORMAT_LEFT)) {
284                 while (--width >= 0) {
285                         string = acpi_ut_bound_string_output(string, end, zero);
286                 }
287         }
288
289         while (i <= --precision) {
290                 string = acpi_ut_bound_string_output(string, end, '0');
291         }
292         while (--i >= 0) {
293                 string = acpi_ut_bound_string_output(string, end,
294                                                      reversed_string[i]);
295         }
296         while (--width >= 0) {
297                 string = acpi_ut_bound_string_output(string, end, ' ');
298         }
299
300         return (string);
301 }
302
303 /*******************************************************************************
304  *
305  * FUNCTION:    vsnprintf
306  *
307  * PARAMETERS:  string              - String with boundary
308  *              size                - Boundary of the string
309  *              format              - Standard printf format
310  *              args                - Argument list
311  *
312  * RETURN:      Number of bytes actually written.
313  *
314  * DESCRIPTION: Formatted output to a string using argument list pointer.
315  *
316  ******************************************************************************/
317
318 int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
319 {
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;
333
334         pos = string;
335
336         if (size != ACPI_UINT32_MAX) {
337                 end = string + size;
338         } else {
339                 end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
340         }
341
342         for (; *format; ++format) {
343                 if (*format != '%') {
344                         pos = acpi_ut_bound_string_output(pos, end, *format);
345                         continue;
346                 }
347
348                 type = 0;
349                 base = 10;
350
351                 /* Process sign */
352
353                 do {
354                         ++format;
355                         if (*format == '#') {
356                                 type |= ACPI_FORMAT_PREFIX;
357                         } else if (*format == '0') {
358                                 type |= ACPI_FORMAT_ZERO;
359                         } else if (*format == '+') {
360                                 type |= ACPI_FORMAT_SIGN_PLUS;
361                         } else if (*format == ' ') {
362                                 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
363                         } else if (*format == '-') {
364                                 type |= ACPI_FORMAT_LEFT;
365                         } else {
366                                 break;
367                         }
368
369                 } while (1);
370
371                 /* Process width */
372
373                 width = -1;
374                 if (isdigit((int)*format)) {
375                         format = acpi_ut_scan_number(format, &number);
376                         width = (s32)number;
377                 } else if (*format == '*') {
378                         ++format;
379                         width = va_arg(args, int);
380                         if (width < 0) {
381                                 width = -width;
382                                 type |= ACPI_FORMAT_LEFT;
383                         }
384                 }
385
386                 /* Process precision */
387
388                 precision = -1;
389                 if (*format == '.') {
390                         ++format;
391                         if (isdigit((int)*format)) {
392                                 format = acpi_ut_scan_number(format, &number);
393                                 precision = (s32)number;
394                         } else if (*format == '*') {
395                                 ++format;
396                                 precision = va_arg(args, int);
397                         }
398
399                         if (precision < 0) {
400                                 precision = 0;
401                         }
402                 }
403
404                 /* Process qualifier */
405
406                 qualifier = -1;
407                 if (*format == 'h' || *format == 'l' || *format == 'L') {
408                         qualifier = *format;
409                         ++format;
410
411                         if (qualifier == 'l' && *format == 'l') {
412                                 qualifier = 'L';
413                                 ++format;
414                         }
415                 }
416
417                 switch (*format) {
418                 case '%':
419
420                         pos = acpi_ut_bound_string_output(pos, end, '%');
421                         continue;
422
423                 case 'c':
424
425                         if (!(type & ACPI_FORMAT_LEFT)) {
426                                 while (--width > 0) {
427                                         pos =
428                                             acpi_ut_bound_string_output(pos,
429                                                                         end,
430                                                                         ' ');
431                                 }
432                         }
433
434                         c = (char)va_arg(args, int);
435                         pos = acpi_ut_bound_string_output(pos, end, c);
436
437                         while (--width > 0) {
438                                 pos =
439                                     acpi_ut_bound_string_output(pos, end, ' ');
440                         }
441                         continue;
442
443                 case 's':
444
445                         s = va_arg(args, char *);
446                         if (!s) {
447                                 s = "<NULL>";
448                         }
449                         length = (s32)acpi_ut_bound_string_length(s, precision);
450                         if (!(type & ACPI_FORMAT_LEFT)) {
451                                 while (length < width--) {
452                                         pos =
453                                             acpi_ut_bound_string_output(pos,
454                                                                         end,
455                                                                         ' ');
456                                 }
457                         }
458
459                         for (i = 0; i < length; ++i) {
460                                 pos = acpi_ut_bound_string_output(pos, end, *s);
461                                 ++s;
462                         }
463
464                         while (length < width--) {
465                                 pos =
466                                     acpi_ut_bound_string_output(pos, end, ' ');
467                         }
468                         continue;
469
470                 case 'o':
471
472                         base = 8;
473                         break;
474
475                 case 'X':
476
477                         type |= ACPI_FORMAT_UPPER;
478                         /* FALLTHROUGH */
479
480                 case 'x':
481
482                         base = 16;
483                         break;
484
485                 case 'd':
486                 case 'i':
487
488                         type |= ACPI_FORMAT_SIGN;
489
490                 case 'u':
491
492                         break;
493
494                 case 'p':
495
496                         if (width == -1) {
497                                 width = 2 * sizeof(void *);
498                                 type |= ACPI_FORMAT_ZERO;
499                         }
500
501                         p = va_arg(args, void *);
502                         pos =
503                             acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
504                                                   16, width, precision, type);
505                         continue;
506
507                 default:
508
509                         pos = acpi_ut_bound_string_output(pos, end, '%');
510                         if (*format) {
511                                 pos =
512                                     acpi_ut_bound_string_output(pos, end,
513                                                                 *format);
514                         } else {
515                                 --format;
516                         }
517                         continue;
518                 }
519
520                 if (qualifier == 'L') {
521                         number = va_arg(args, u64);
522                         if (type & ACPI_FORMAT_SIGN) {
523                                 number = (s64)number;
524                         }
525                 } else if (qualifier == 'l') {
526                         number = va_arg(args, unsigned long);
527                         if (type & ACPI_FORMAT_SIGN) {
528                                 number = (s32)number;
529                         }
530                 } else if (qualifier == 'h') {
531                         number = (u16)va_arg(args, int);
532                         if (type & ACPI_FORMAT_SIGN) {
533                                 number = (s16)number;
534                         }
535                 } else {
536                         number = va_arg(args, unsigned int);
537                         if (type & ACPI_FORMAT_SIGN) {
538                                 number = (signed int)number;
539                         }
540                 }
541
542                 pos = acpi_ut_format_number(pos, end, number, base,
543                                             width, precision, type);
544         }
545
546         if (size > 0) {
547                 if (pos < end) {
548                         *pos = '\0';
549                 } else {
550                         end[-1] = '\0';
551                 }
552         }
553
554         return ((int)ACPI_PTR_DIFF(pos, string));
555 }
556
557 /*******************************************************************************
558  *
559  * FUNCTION:    snprintf
560  *
561  * PARAMETERS:  string              - String with boundary
562  *              size                - Boundary of the string
563  *              Format, ...         - Standard printf format
564  *
565  * RETURN:      Number of bytes actually written.
566  *
567  * DESCRIPTION: Formatted output to a string.
568  *
569  ******************************************************************************/
570
571 int snprintf(char *string, acpi_size size, const char *format, ...)
572 {
573         va_list args;
574         int length;
575
576         va_start(args, format);
577         length = vsnprintf(string, size, format, args);
578         va_end(args);
579
580         return (length);
581 }
582
583 /*******************************************************************************
584  *
585  * FUNCTION:    sprintf
586  *
587  * PARAMETERS:  string              - String with boundary
588  *              Format, ...         - Standard printf format
589  *
590  * RETURN:      Number of bytes actually written.
591  *
592  * DESCRIPTION: Formatted output to a string.
593  *
594  ******************************************************************************/
595
596 int sprintf(char *string, const char *format, ...)
597 {
598         va_list args;
599         int length;
600
601         va_start(args, format);
602         length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
603         va_end(args);
604
605         return (length);
606 }
607
608 #ifdef ACPI_APPLICATION
609 /*******************************************************************************
610  *
611  * FUNCTION:    vprintf
612  *
613  * PARAMETERS:  format              - Standard printf format
614  *              args                - Argument list
615  *
616  * RETURN:      Number of bytes actually written.
617  *
618  * DESCRIPTION: Formatted output to stdout using argument list pointer.
619  *
620  ******************************************************************************/
621
622 int vprintf(const char *format, va_list args)
623 {
624         acpi_cpu_flags flags;
625         int length;
626
627         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
628         length = vsnprintf(acpi_gbl_print_buffer,
629                            sizeof(acpi_gbl_print_buffer), format, args);
630
631         (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
632         acpi_os_release_lock(acpi_gbl_print_lock, flags);
633
634         return (length);
635 }
636
637 /*******************************************************************************
638  *
639  * FUNCTION:    printf
640  *
641  * PARAMETERS:  Format, ...         - Standard printf format
642  *
643  * RETURN:      Number of bytes actually written.
644  *
645  * DESCRIPTION: Formatted output to stdout.
646  *
647  ******************************************************************************/
648
649 int printf(const char *format, ...)
650 {
651         va_list args;
652         int length;
653
654         va_start(args, format);
655         length = vprintf(format, args);
656         va_end(args);
657
658         return (length);
659 }
660
661 /*******************************************************************************
662  *
663  * FUNCTION:    vfprintf
664  *
665  * PARAMETERS:  file                - File descriptor
666  *              format              - Standard printf format
667  *              args                - Argument list
668  *
669  * RETURN:      Number of bytes actually written.
670  *
671  * DESCRIPTION: Formatted output to a file using argument list pointer.
672  *
673  ******************************************************************************/
674
675 int vfprintf(FILE * file, const char *format, va_list args)
676 {
677         acpi_cpu_flags flags;
678         int length;
679
680         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
681         length = vsnprintf(acpi_gbl_print_buffer,
682                            sizeof(acpi_gbl_print_buffer), format, args);
683
684         (void)fwrite(acpi_gbl_print_buffer, length, 1, file);
685         acpi_os_release_lock(acpi_gbl_print_lock, flags);
686
687         return (length);
688 }
689
690 /*******************************************************************************
691  *
692  * FUNCTION:    fprintf
693  *
694  * PARAMETERS:  file                - File descriptor
695  *              Format, ...         - Standard printf format
696  *
697  * RETURN:      Number of bytes actually written.
698  *
699  * DESCRIPTION: Formatted output to a file.
700  *
701  ******************************************************************************/
702
703 int fprintf(FILE * file, const char *format, ...)
704 {
705         va_list args;
706         int length;
707
708         va_start(args, format);
709         length = vfprintf(file, format, args);
710         va_end(args);
711
712         return (length);
713 }
714 #endif