1 /****************************************************************************** 2 * 3 * Module Name: utprint - Formatted printing routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #include "acpi.h" 44 #include "accommon.h" 45 46 #define _COMPONENT ACPI_UTILITIES 47 ACPI_MODULE_NAME ("utprint") 48 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 58 59 /* Local prototypes */ 60 61 static ACPI_SIZE 62 AcpiUtBoundStringLength ( 63 const char *String, 64 ACPI_SIZE Count); 65 66 static char * 67 AcpiUtBoundStringOutput ( 68 char *String, 69 const char *End, 70 char c); 71 72 static char * 73 AcpiUtFormatNumber ( 74 char *String, 75 char *End, 76 UINT64 Number, 77 UINT8 Base, 78 INT32 Width, 79 INT32 Precision, 80 UINT8 Type); 81 82 static char * 83 AcpiUtPutNumber ( 84 char *String, 85 UINT64 Number, 86 UINT8 Base, 87 BOOLEAN Upper); 88 89 90 /******************************************************************************* 91 * 92 * FUNCTION: AcpiUtBoundStringLength 93 * 94 * PARAMETERS: String - String with boundary 95 * Count - Boundary of the string 96 * 97 * RETURN: Length of the string. Less than or equal to Count. 98 * 99 * DESCRIPTION: Calculate the length of a string with boundary. 100 * 101 ******************************************************************************/ 102 103 static ACPI_SIZE 104 AcpiUtBoundStringLength ( 105 const char *String, 106 ACPI_SIZE Count) 107 { 108 UINT32 Length = 0; 109 110 111 while (*String && Count) 112 { 113 Length++; 114 String++; 115 Count--; 116 } 117 118 return (Length); 119 } 120 121 122 /******************************************************************************* 123 * 124 * FUNCTION: AcpiUtBoundStringOutput 125 * 126 * PARAMETERS: String - String with boundary 127 * End - Boundary of the string 128 * c - Character to be output to the string 129 * 130 * RETURN: Updated position for next valid character 131 * 132 * DESCRIPTION: Output a character into a string with boundary check. 133 * 134 ******************************************************************************/ 135 136 static char * 137 AcpiUtBoundStringOutput ( 138 char *String, 139 const char *End, 140 char c) 141 { 142 143 if (String < End) 144 { 145 *String = c; 146 } 147 148 ++String; 149 return (String); 150 } 151 152 153 /******************************************************************************* 154 * 155 * FUNCTION: AcpiUtPutNumber 156 * 157 * PARAMETERS: String - Buffer to hold reverse-ordered string 158 * Number - Integer to be converted 159 * Base - Base of the integer 160 * Upper - Whether or not using upper cased digits 161 * 162 * RETURN: Updated position for next valid character 163 * 164 * DESCRIPTION: Convert an integer into a string, note that, the string holds a 165 * reversed ordered number without the trailing zero. 166 * 167 ******************************************************************************/ 168 169 static char * 170 AcpiUtPutNumber ( 171 char *String, 172 UINT64 Number, 173 UINT8 Base, 174 BOOLEAN Upper) 175 { 176 const char *Digits; 177 UINT64 DigitIndex; 178 char *Pos; 179 180 181 Pos = String; 182 Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits; 183 184 if (Number == 0) 185 { 186 *(Pos++) = '0'; 187 } 188 else 189 { 190 while (Number) 191 { 192 (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex); 193 *(Pos++) = Digits[DigitIndex]; 194 } 195 } 196 197 /* *(Pos++) = '0'; */ 198 return (Pos); 199 } 200 201 202 /******************************************************************************* 203 * 204 * FUNCTION: AcpiUtScanNumber 205 * 206 * PARAMETERS: String - String buffer 207 * NumberPtr - Where the number is returned 208 * 209 * RETURN: Updated position for next valid character 210 * 211 * DESCRIPTION: Scan a string for a decimal integer. 212 * 213 ******************************************************************************/ 214 215 const char * 216 AcpiUtScanNumber ( 217 const char *String, 218 UINT64 *NumberPtr) 219 { 220 UINT64 Number = 0; 221 222 223 while (isdigit ((int) *String)) 224 { 225 Number *= 10; 226 Number += *(String++) - '0'; 227 } 228 229 *NumberPtr = Number; 230 return (String); 231 } 232 233 234 /******************************************************************************* 235 * 236 * FUNCTION: AcpiUtPrintNumber 237 * 238 * PARAMETERS: String - String buffer 239 * Number - The number to be converted 240 * 241 * RETURN: Updated position for next valid character 242 * 243 * DESCRIPTION: Print a decimal integer into a string. 244 * 245 ******************************************************************************/ 246 247 const char * 248 AcpiUtPrintNumber ( 249 char *String, 250 UINT64 Number) 251 { 252 char AsciiString[20]; 253 const char *Pos1; 254 char *Pos2; 255 256 257 Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE); 258 Pos2 = String; 259 260 while (Pos1 != AsciiString) 261 { 262 *(Pos2++) = *(--Pos1); 263 } 264 265 *Pos2 = 0; 266 return (String); 267 } 268 269 270 /******************************************************************************* 271 * 272 * FUNCTION: AcpiUtFormatNumber 273 * 274 * PARAMETERS: String - String buffer with boundary 275 * End - Boundary of the string 276 * Number - The number to be converted 277 * Base - Base of the integer 278 * Width - Field width 279 * Precision - Precision of the integer 280 * Type - Special printing flags 281 * 282 * RETURN: Updated position for next valid character 283 * 284 * DESCRIPTION: Print an integer into a string with any base and any precision. 285 * 286 ******************************************************************************/ 287 288 static char * 289 AcpiUtFormatNumber ( 290 char *String, 291 char *End, 292 UINT64 Number, 293 UINT8 Base, 294 INT32 Width, 295 INT32 Precision, 296 UINT8 Type) 297 { 298 char *Pos; 299 char Sign; 300 char Zero; 301 BOOLEAN NeedPrefix; 302 BOOLEAN Upper; 303 INT32 i; 304 char ReversedString[66]; 305 306 307 /* Parameter validation */ 308 309 if (Base < 2 || Base > 16) 310 { 311 return (NULL); 312 } 313 314 if (Type & ACPI_FORMAT_LEFT) 315 { 316 Type &= ~ACPI_FORMAT_ZERO; 317 } 318 319 NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE; 320 Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE; 321 Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' '; 322 323 /* Calculate size according to sign and prefix */ 324 325 Sign = '\0'; 326 if (Type & ACPI_FORMAT_SIGN) 327 { 328 if ((INT64) Number < 0) 329 { 330 Sign = '-'; 331 Number = - (INT64) Number; 332 Width--; 333 } 334 else if (Type & ACPI_FORMAT_SIGN_PLUS) 335 { 336 Sign = '+'; 337 Width--; 338 } 339 else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE) 340 { 341 Sign = ' '; 342 Width--; 343 } 344 } 345 if (NeedPrefix) 346 { 347 Width--; 348 if (Base == 16) 349 { 350 Width--; 351 } 352 } 353 354 /* Generate full string in reverse order */ 355 356 Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper); 357 i = ACPI_PTR_DIFF (Pos, ReversedString); 358 359 /* Printing 100 using %2d gives "100", not "00" */ 360 361 if (i > Precision) 362 { 363 Precision = i; 364 } 365 366 Width -= Precision; 367 368 /* Output the string */ 369 370 if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) 371 { 372 while (--Width >= 0) 373 { 374 String = AcpiUtBoundStringOutput (String, End, ' '); 375 } 376 } 377 if (Sign) 378 { 379 String = AcpiUtBoundStringOutput (String, End, Sign); 380 } 381 if (NeedPrefix) 382 { 383 String = AcpiUtBoundStringOutput (String, End, '0'); 384 if (Base == 16) 385 { 386 String = AcpiUtBoundStringOutput ( 387 String, End, Upper ? 'X' : 'x'); 388 } 389 } 390 if (!(Type & ACPI_FORMAT_LEFT)) 391 { 392 while (--Width >= 0) 393 { 394 String = AcpiUtBoundStringOutput (String, End, Zero); 395 } 396 } 397 398 while (i <= --Precision) 399 { 400 String = AcpiUtBoundStringOutput (String, End, '0'); 401 } 402 while (--i >= 0) 403 { 404 String = AcpiUtBoundStringOutput (String, End, 405 ReversedString[i]); 406 } 407 while (--Width >= 0) 408 { 409 String = AcpiUtBoundStringOutput (String, End, ' '); 410 } 411 412 return (String); 413 } 414 415 #undef sprintf 416 #undef snprintf 417 #undef vsnprintf 418 /******************************************************************************* 419 * 420 * FUNCTION: vsnprintf 421 * 422 * PARAMETERS: String - String with boundary 423 * Size - Boundary of the string 424 * Format - Standard printf format 425 * Args - Argument list 426 * 427 * RETURN: Number of bytes actually written. 428 * 429 * DESCRIPTION: Formatted output to a string using argument list pointer. 430 * 431 ******************************************************************************/ 432 433 int 434 vsnprintf ( 435 char *String, 436 ACPI_SIZE Size, 437 const char *Format, 438 va_list Args) 439 { 440 UINT8 Base; 441 UINT8 Type; 442 INT32 Width; 443 INT32 Precision; 444 char Qualifier; 445 UINT64 Number; 446 char *Pos; 447 char *End; 448 char c; 449 const char *s; 450 const void *p; 451 INT32 Length; 452 int i; 453 454 455 Pos = String; 456 End = String + Size; 457 458 for (; *Format; ++Format) 459 { 460 if (*Format != '%') 461 { 462 Pos = AcpiUtBoundStringOutput (Pos, End, *Format); 463 continue; 464 } 465 466 Type = 0; 467 Base = 10; 468 469 /* Process sign */ 470 471 do 472 { 473 ++Format; 474 if (*Format == '#') 475 { 476 Type |= ACPI_FORMAT_PREFIX; 477 } 478 else if (*Format == '0') 479 { 480 Type |= ACPI_FORMAT_ZERO; 481 } 482 else if (*Format == '+') 483 { 484 Type |= ACPI_FORMAT_SIGN_PLUS; 485 } 486 else if (*Format == ' ') 487 { 488 Type |= ACPI_FORMAT_SIGN_PLUS_SPACE; 489 } 490 else if (*Format == '-') 491 { 492 Type |= ACPI_FORMAT_LEFT; 493 } 494 else 495 { 496 break; 497 } 498 499 } while (1); 500 501 /* Process width */ 502 503 Width = -1; 504 if (isdigit ((int) *Format)) 505 { 506 Format = AcpiUtScanNumber (Format, &Number); 507 Width = (INT32) Number; 508 } 509 else if (*Format == '*') 510 { 511 ++Format; 512 Width = va_arg (Args, int); 513 if (Width < 0) 514 { 515 Width = -Width; 516 Type |= ACPI_FORMAT_LEFT; 517 } 518 } 519 520 /* Process precision */ 521 522 Precision = -1; 523 if (*Format == '.') 524 { 525 ++Format; 526 if (isdigit ((int) *Format)) 527 { 528 Format = AcpiUtScanNumber (Format, &Number); 529 Precision = (INT32) Number; 530 } 531 else if (*Format == '*') 532 { 533 ++Format; 534 Precision = va_arg (Args, int); 535 } 536 537 if (Precision < 0) 538 { 539 Precision = 0; 540 } 541 } 542 543 /* Process qualifier */ 544 545 Qualifier = -1; 546 if (*Format == 'h' || *Format == 'l' || *Format == 'L') 547 { 548 Qualifier = *Format; 549 ++Format; 550 551 if (Qualifier == 'l' && *Format == 'l') 552 { 553 Qualifier = 'L'; 554 ++Format; 555 } 556 } 557 558 switch (*Format) 559 { 560 case '%': 561 562 Pos = AcpiUtBoundStringOutput (Pos, End, '%'); 563 continue; 564 565 case 'c': 566 567 if (!(Type & ACPI_FORMAT_LEFT)) 568 { 569 while (--Width > 0) 570 { 571 Pos = AcpiUtBoundStringOutput (Pos, End, ' '); 572 } 573 } 574 575 c = (char) va_arg (Args, int); 576 Pos = AcpiUtBoundStringOutput (Pos, End, c); 577 578 while (--Width > 0) 579 { 580 Pos = AcpiUtBoundStringOutput (Pos, End, ' '); 581 } 582 continue; 583 584 case 's': 585 586 s = va_arg (Args, char *); 587 if (!s) 588 { 589 s = "<NULL>"; 590 } 591 Length = AcpiUtBoundStringLength (s, Precision); 592 if (!(Type & ACPI_FORMAT_LEFT)) 593 { 594 while (Length < Width--) 595 { 596 Pos = AcpiUtBoundStringOutput (Pos, End, ' '); 597 } 598 } 599 600 for (i = 0; i < Length; ++i) 601 { 602 Pos = AcpiUtBoundStringOutput (Pos, End, *s); 603 ++s; 604 } 605 606 while (Length < Width--) 607 { 608 Pos = AcpiUtBoundStringOutput (Pos, End, ' '); 609 } 610 continue; 611 612 case 'o': 613 614 Base = 8; 615 break; 616 617 case 'X': 618 619 Type |= ACPI_FORMAT_UPPER; 620 621 case 'x': 622 623 Base = 16; 624 break; 625 626 case 'd': 627 case 'i': 628 629 Type |= ACPI_FORMAT_SIGN; 630 631 case 'u': 632 633 break; 634 635 case 'p': 636 637 if (Width == -1) 638 { 639 Width = 2 * sizeof (void *); 640 Type |= ACPI_FORMAT_ZERO; 641 } 642 643 p = va_arg (Args, void *); 644 Pos = AcpiUtFormatNumber ( 645 Pos, End, ACPI_TO_INTEGER (p), 16, Width, Precision, Type); 646 continue; 647 648 default: 649 650 Pos = AcpiUtBoundStringOutput (Pos, End, '%'); 651 if (*Format) 652 { 653 Pos = AcpiUtBoundStringOutput (Pos, End, *Format); 654 } 655 else 656 { 657 --Format; 658 } 659 continue; 660 } 661 662 if (Qualifier == 'L') 663 { 664 Number = va_arg (Args, UINT64); 665 if (Type & ACPI_FORMAT_SIGN) 666 { 667 Number = (INT64) Number; 668 } 669 } 670 else if (Qualifier == 'l') 671 { 672 Number = va_arg (Args, unsigned long); 673 if (Type & ACPI_FORMAT_SIGN) 674 { 675 Number = (INT32) Number; 676 } 677 } 678 else if (Qualifier == 'h') 679 { 680 Number = (UINT16) va_arg (Args, int); 681 if (Type & ACPI_FORMAT_SIGN) 682 { 683 Number = (INT16) Number; 684 } 685 } 686 else 687 { 688 Number = va_arg (Args, unsigned int); 689 if (Type & ACPI_FORMAT_SIGN) 690 { 691 Number = (signed int) Number; 692 } 693 } 694 695 Pos = AcpiUtFormatNumber (Pos, End, Number, Base, 696 Width, Precision, Type); 697 } 698 699 if (Size > 0) 700 { 701 if (Pos < End) 702 { 703 *Pos = '\0'; 704 } 705 else 706 { 707 End[-1] = '\0'; 708 } 709 } 710 711 return (ACPI_PTR_DIFF (Pos, String)); 712 } 713 714 715 /******************************************************************************* 716 * 717 * FUNCTION: snprintf 718 * 719 * PARAMETERS: String - String with boundary 720 * Size - Boundary of the string 721 * Format, ... - Standard printf format 722 * 723 * RETURN: Number of bytes actually written. 724 * 725 * DESCRIPTION: Formatted output to a string. 726 * 727 ******************************************************************************/ 728 729 int 730 snprintf ( 731 char *String, 732 ACPI_SIZE Size, 733 const char *Format, 734 ...) 735 { 736 va_list Args; 737 int Length; 738 739 740 va_start (Args, Format); 741 Length = vsnprintf (String, Size, Format, Args); 742 va_end (Args); 743 744 return (Length); 745 } 746 747 748 /******************************************************************************* 749 * 750 * FUNCTION: sprintf 751 * 752 * PARAMETERS: String - String with boundary 753 * Format, ... - Standard printf format 754 * 755 * RETURN: Number of bytes actually written. 756 * 757 * DESCRIPTION: Formatted output to a string. 758 * 759 ******************************************************************************/ 760 761 int 762 sprintf ( 763 char *String, 764 const char *Format, 765 ...) 766 { 767 va_list Args; 768 int Length; 769 770 771 va_start (Args, Format); 772 Length = vsnprintf (String, ACPI_UINT32_MAX, Format, Args); 773 va_end (Args); 774 775 return (Length); 776 } 777 778 779 #ifdef ACPI_APPLICATION 780 /******************************************************************************* 781 * 782 * FUNCTION: vprintf 783 * 784 * PARAMETERS: Format - Standard printf format 785 * Args - Argument list 786 * 787 * RETURN: Number of bytes actually written. 788 * 789 * DESCRIPTION: Formatted output to stdout using argument list pointer. 790 * 791 ******************************************************************************/ 792 793 int 794 vprintf ( 795 const char *Format, 796 va_list Args) 797 { 798 ACPI_CPU_FLAGS Flags; 799 int Length; 800 801 802 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock); 803 Length = vsnprintf (AcpiGbl_PrintBuffer, 804 sizeof (AcpiGbl_PrintBuffer), Format, Args); 805 806 (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, ACPI_FILE_OUT); 807 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags); 808 809 return (Length); 810 } 811 812 813 /******************************************************************************* 814 * 815 * FUNCTION: printf 816 * 817 * PARAMETERS: Format, ... - Standard printf format 818 * 819 * RETURN: Number of bytes actually written. 820 * 821 * DESCRIPTION: Formatted output to stdout. 822 * 823 ******************************************************************************/ 824 825 int 826 printf ( 827 const char *Format, 828 ...) 829 { 830 va_list Args; 831 int Length; 832 833 834 va_start (Args, Format); 835 Length = vprintf (Format, Args); 836 va_end (Args); 837 838 return (Length); 839 } 840 841 842 /******************************************************************************* 843 * 844 * FUNCTION: vfprintf 845 * 846 * PARAMETERS: File - File descriptor 847 * Format - Standard printf format 848 * Args - Argument list 849 * 850 * RETURN: Number of bytes actually written. 851 * 852 * DESCRIPTION: Formatted output to a file using argument list pointer. 853 * 854 ******************************************************************************/ 855 856 int 857 vfprintf ( 858 FILE *File, 859 const char *Format, 860 va_list Args) 861 { 862 ACPI_CPU_FLAGS Flags; 863 int Length; 864 865 866 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock); 867 Length = vsnprintf (AcpiGbl_PrintBuffer, 868 sizeof (AcpiGbl_PrintBuffer), Format, Args); 869 870 (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, File); 871 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags); 872 873 return (Length); 874 } 875 876 877 /******************************************************************************* 878 * 879 * FUNCTION: fprintf 880 * 881 * PARAMETERS: File - File descriptor 882 * Format, ... - Standard printf format 883 * 884 * RETURN: Number of bytes actually written. 885 * 886 * DESCRIPTION: Formatted output to a file. 887 * 888 ******************************************************************************/ 889 890 int 891 fprintf ( 892 FILE *File, 893 const char *Format, 894 ...) 895 { 896 va_list Args; 897 int Length; 898 899 900 va_start (Args, Format); 901 Length = vfprintf (File, Format, Args); 902 va_end (Args); 903 904 return (Length); 905 } 906 #endif 907