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