root/drivers/acpi/acpica/utprint.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_ut_bound_string_length
  2. acpi_ut_bound_string_output
  3. acpi_ut_put_number
  4. acpi_ut_scan_number
  5. acpi_ut_print_number
  6. acpi_ut_format_number
  7. vsnprintf
  8. snprintf
  9. sprintf
  10. vprintf
  11. printf
  12. vfprintf
  13. fprintf

   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 - 2019, 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         end = string + size;
 336 
 337         for (; *format; ++format) {
 338                 if (*format != '%') {
 339                         pos = acpi_ut_bound_string_output(pos, end, *format);
 340                         continue;
 341                 }
 342 
 343                 type = 0;
 344                 base = 10;
 345 
 346                 /* Process sign */
 347 
 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;
 362                         }
 363 
 364                 } while (1);
 365 
 366                 /* Process width */
 367 
 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;
 378                         }
 379                 }
 380 
 381                 /* Process precision */
 382 
 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);
 392                         }
 393 
 394                         if (precision < 0) {
 395                                 precision = 0;
 396                         }
 397                 }
 398 
 399                 /* Process qualifier */
 400 
 401                 qualifier = -1;
 402                 if (*format == 'h' || *format == 'l' || *format == 'L') {
 403                         qualifier = *format;
 404                         ++format;
 405 
 406                         if (qualifier == 'l' && *format == 'l') {
 407                                 qualifier = 'L';
 408                                 ++format;
 409                         }
 410                 }
 411 
 412                 switch (*format) {
 413                 case '%':
 414 
 415                         pos = acpi_ut_bound_string_output(pos, end, '%');
 416                         continue;
 417 
 418                 case 'c':
 419 
 420                         if (!(type & ACPI_FORMAT_LEFT)) {
 421                                 while (--width > 0) {
 422                                         pos =
 423                                             acpi_ut_bound_string_output(pos,
 424                                                                         end,
 425                                                                         ' ');
 426                                 }
 427                         }
 428 
 429                         c = (char)va_arg(args, int);
 430                         pos = acpi_ut_bound_string_output(pos, end, c);
 431 
 432                         while (--width > 0) {
 433                                 pos =
 434                                     acpi_ut_bound_string_output(pos, end, ' ');
 435                         }
 436                         continue;
 437 
 438                 case 's':
 439 
 440                         s = va_arg(args, char *);
 441                         if (!s) {
 442                                 s = "<NULL>";
 443                         }
 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                                                                         ' ');
 451                                 }
 452                         }
 453 
 454                         for (i = 0; i < length; ++i) {
 455                                 pos = acpi_ut_bound_string_output(pos, end, *s);
 456                                 ++s;
 457                         }
 458 
 459                         while (length < width--) {
 460                                 pos =
 461                                     acpi_ut_bound_string_output(pos, end, ' ');
 462                         }
 463                         continue;
 464 
 465                 case 'o':
 466 
 467                         base = 8;
 468                         break;
 469 
 470                 case 'X':
 471 
 472                         type |= ACPI_FORMAT_UPPER;
 473                         /* FALLTHROUGH */
 474 
 475                 case 'x':
 476 
 477                         base = 16;
 478                         break;
 479 
 480                 case 'd':
 481                 case 'i':
 482 
 483                         type |= ACPI_FORMAT_SIGN;
 484 
 485                 case 'u':
 486 
 487                         break;
 488 
 489                 case 'p':
 490 
 491                         if (width == -1) {
 492                                 width = 2 * sizeof(void *);
 493                                 type |= ACPI_FORMAT_ZERO;
 494                         }
 495 
 496                         p = va_arg(args, void *);
 497                         pos =
 498                             acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
 499                                                   16, width, precision, type);
 500                         continue;
 501 
 502                 default:
 503 
 504                         pos = acpi_ut_bound_string_output(pos, end, '%');
 505                         if (*format) {
 506                                 pos =
 507                                     acpi_ut_bound_string_output(pos, end,
 508                                                                 *format);
 509                         } else {
 510                                 --format;
 511                         }
 512                         continue;
 513                 }
 514 
 515                 if (qualifier == 'L') {
 516                         number = va_arg(args, u64);
 517                         if (type & ACPI_FORMAT_SIGN) {
 518                                 number = (s64)number;
 519                         }
 520                 } else if (qualifier == 'l') {
 521                         number = va_arg(args, unsigned long);
 522                         if (type & ACPI_FORMAT_SIGN) {
 523                                 number = (s32)number;
 524                         }
 525                 } else if (qualifier == 'h') {
 526                         number = (u16)va_arg(args, int);
 527                         if (type & ACPI_FORMAT_SIGN) {
 528                                 number = (s16)number;
 529                         }
 530                 } else {
 531                         number = va_arg(args, unsigned int);
 532                         if (type & ACPI_FORMAT_SIGN) {
 533                                 number = (signed int)number;
 534                         }
 535                 }
 536 
 537                 pos = acpi_ut_format_number(pos, end, number, base,
 538                                             width, precision, type);
 539         }
 540 
 541         if (size > 0) {
 542                 if (pos < end) {
 543                         *pos = '\0';
 544                 } else {
 545                         end[-1] = '\0';
 546                 }
 547         }
 548 
 549         return ((int)ACPI_PTR_DIFF(pos, string));
 550 }
 551 
 552 /*******************************************************************************
 553  *
 554  * FUNCTION:    snprintf
 555  *
 556  * PARAMETERS:  string              - String with boundary
 557  *              size                - Boundary of the string
 558  *              Format, ...         - Standard printf format
 559  *
 560  * RETURN:      Number of bytes actually written.
 561  *
 562  * DESCRIPTION: Formatted output to a string.
 563  *
 564  ******************************************************************************/
 565 
 566 int snprintf(char *string, acpi_size size, const char *format, ...)
 567 {
 568         va_list args;
 569         int length;
 570 
 571         va_start(args, format);
 572         length = vsnprintf(string, size, format, args);
 573         va_end(args);
 574 
 575         return (length);
 576 }
 577 
 578 /*******************************************************************************
 579  *
 580  * FUNCTION:    sprintf
 581  *
 582  * PARAMETERS:  string              - String with boundary
 583  *              Format, ...         - Standard printf format
 584  *
 585  * RETURN:      Number of bytes actually written.
 586  *
 587  * DESCRIPTION: Formatted output to a string.
 588  *
 589  ******************************************************************************/
 590 
 591 int sprintf(char *string, const char *format, ...)
 592 {
 593         va_list args;
 594         int length;
 595 
 596         va_start(args, format);
 597         length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
 598         va_end(args);
 599 
 600         return (length);
 601 }
 602 
 603 #ifdef ACPI_APPLICATION
 604 /*******************************************************************************
 605  *
 606  * FUNCTION:    vprintf
 607  *
 608  * PARAMETERS:  format              - Standard printf format
 609  *              args                - Argument list
 610  *
 611  * RETURN:      Number of bytes actually written.
 612  *
 613  * DESCRIPTION: Formatted output to stdout using argument list pointer.
 614  *
 615  ******************************************************************************/
 616 
 617 int vprintf(const char *format, va_list args)
 618 {
 619         acpi_cpu_flags flags;
 620         int length;
 621 
 622         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
 623         length = vsnprintf(acpi_gbl_print_buffer,
 624                            sizeof(acpi_gbl_print_buffer), format, args);
 625 
 626         (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
 627         acpi_os_release_lock(acpi_gbl_print_lock, flags);
 628 
 629         return (length);
 630 }
 631 
 632 /*******************************************************************************
 633  *
 634  * FUNCTION:    printf
 635  *
 636  * PARAMETERS:  Format, ...         - Standard printf format
 637  *
 638  * RETURN:      Number of bytes actually written.
 639  *
 640  * DESCRIPTION: Formatted output to stdout.
 641  *
 642  ******************************************************************************/
 643 
 644 int printf(const char *format, ...)
 645 {
 646         va_list args;
 647         int length;
 648 
 649         va_start(args, format);
 650         length = vprintf(format, args);
 651         va_end(args);
 652 
 653         return (length);
 654 }
 655 
 656 /*******************************************************************************
 657  *
 658  * FUNCTION:    vfprintf
 659  *
 660  * PARAMETERS:  file                - File descriptor
 661  *              format              - Standard printf format
 662  *              args                - Argument list
 663  *
 664  * RETURN:      Number of bytes actually written.
 665  *
 666  * DESCRIPTION: Formatted output to a file using argument list pointer.
 667  *
 668  ******************************************************************************/
 669 
 670 int vfprintf(FILE * file, const char *format, va_list args)
 671 {
 672         acpi_cpu_flags flags;
 673         int length;
 674 
 675         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
 676         length = vsnprintf(acpi_gbl_print_buffer,
 677                            sizeof(acpi_gbl_print_buffer), format, args);
 678 
 679         (void)fwrite(acpi_gbl_print_buffer, length, 1, file);
 680         acpi_os_release_lock(acpi_gbl_print_lock, flags);
 681 
 682         return (length);
 683 }
 684 
 685 /*******************************************************************************
 686  *
 687  * FUNCTION:    fprintf
 688  *
 689  * PARAMETERS:  file                - File descriptor
 690  *              Format, ...         - Standard printf format
 691  *
 692  * RETURN:      Number of bytes actually written.
 693  *
 694  * DESCRIPTION: Formatted output to a file.
 695  *
 696  ******************************************************************************/
 697 
 698 int fprintf(FILE * file, const char *format, ...)
 699 {
 700         va_list args;
 701         int length;
 702 
 703         va_start(args, format);
 704         length = vfprintf(file, format, args);
 705         va_end(args);
 706 
 707         return (length);
 708 }
 709 #endif

/* [<][>][^][v][top][bottom][index][help] */