1 /******************************************************************************
   2  *
   3  * Module Name: utprint - Formatted printing routines
   4  *
   5  *****************************************************************************/
   6 
   7 /******************************************************************************
   8  *
   9  * 1. Copyright Notice
  10  *
  11  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
  12  * All rights reserved.
  13  *
  14  * 2. License
  15  *
  16  * 2.1. This is your license from Intel Corp. under its intellectual property
  17  * rights. You may have additional license terms from the party that provided
  18  * you this software, covering your right to use that party's intellectual
  19  * property rights.
  20  *
  21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22  * copy of the source code appearing in this file ("Covered Code") an
  23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25  * make derivatives, distribute, use and display any portion of the Covered
  26  * Code in any form, with the right to sublicense such rights; and
  27  *
  28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29  * license (with the right to sublicense), under only those claims of Intel
  30  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31  * offer to sell, and import the Covered Code and derivative works thereof
  32  * solely to the minimum extent necessary to exercise the above copyright
  33  * license, and in no event shall the patent license extend to any additions
  34  * to or modifications of the Original Intel Code. No other license or right
  35  * is granted directly or by implication, estoppel or otherwise;
  36  *
  37  * The above copyright and patent license is granted only if the following
  38  * conditions are met:
  39  *
  40  * 3. Conditions
  41  *
  42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43  * Redistribution of source code of any substantial portion of the Covered
  44  * Code or modification with rights to further distribute source must include
  45  * the above Copyright Notice, the above License, this list of Conditions,
  46  * and the following Disclaimer and Export Compliance provision. In addition,
  47  * Licensee must cause all Covered Code to which Licensee contributes to
  48  * contain a file documenting the changes Licensee made to create that Covered
  49  * Code and the date of any change. Licensee must include in that file the
  50  * documentation of any changes made by any predecessor Licensee. Licensee
  51  * must include a prominent statement that the modification is derived,
  52  * directly or indirectly, from Original Intel Code.
  53  *
  54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55  * Redistribution of source code of any substantial portion of the Covered
  56  * Code or modification without rights to further distribute source must
  57  * include the following Disclaimer and Export Compliance provision in the
  58  * documentation and/or other materials provided with distribution. In
  59  * addition, Licensee may not authorize further sublicense of source of any
  60  * portion of the Covered Code, and must include terms to the effect that the
  61  * license from Licensee to its licensee is limited to the intellectual
  62  * property embodied in the software Licensee provides to its licensee, and
  63  * not to intellectual property embodied in modifications its licensee may
  64  * make.
  65  *
  66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67  * substantial portion of the Covered Code or modification must reproduce the
  68  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69  * provision in the documentation and/or other materials provided with the
  70  * distribution.
  71  *
  72  * 3.4. Intel retains all right, title, and interest in and to the Original
  73  * Intel Code.
  74  *
  75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77  * other dealings in products derived from or relating to the Covered Code
  78  * without prior written authorization from Intel.
  79  *
  80  * 4. Disclaimer and Export Compliance
  81  *
  82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
  85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
  86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
  87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88  * PARTICULAR PURPOSE.
  89  *
  90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
  96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97  * LIMITED REMEDY.
  98  *
  99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
 100  * software or system incorporating such software without first obtaining any
 101  * required license or other approval from the U. S. Department of Commerce or
 102  * any other agency or department of the United States Government. In the
 103  * event Licensee exports any such software from the United States or
 104  * re-exports any such software from a foreign destination, Licensee shall
 105  * ensure that the distribution and export/re-export of the software is in
 106  * compliance with all laws, regulations, orders, or other restrictions of the
 107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
 108  * any of its subsidiaries will export/re-export any technical data, process,
 109  * software, or service, directly or indirectly, to any country for which the
 110  * United States government or any agency thereof requires an export license,
 111  * other governmental approval, or letter of assurance, without first obtaining
 112  * such license, approval or letter.
 113  *
 114  *****************************************************************************
 115  *
 116  * Alternatively, you may choose to be licensed under the terms of the
 117  * following license:
 118  *
 119  * Redistribution and use in source and binary forms, with or without
 120  * modification, are permitted provided that the following conditions
 121  * are met:
 122  * 1. Redistributions of source code must retain the above copyright
 123  *    notice, this list of conditions, and the following disclaimer,
 124  *    without modification.
 125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 126  *    substantially similar to the "NO WARRANTY" disclaimer below
 127  *    ("Disclaimer") and any redistribution must be conditioned upon
 128  *    including a substantially similar Disclaimer requirement for further
 129  *    binary redistribution.
 130  * 3. Neither the names of the above-listed copyright holders nor the names
 131  *    of any contributors may be used to endorse or promote products derived
 132  *    from this software without specific prior written permission.
 133  *
 134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 145  *
 146  * Alternatively, you may choose to be licensed under the terms of the
 147  * GNU General Public License ("GPL") version 2 as published by the Free
 148  * Software Foundation.
 149  *
 150  *****************************************************************************/
 151 
 152 #include "acpi.h"
 153 #include "accommon.h"
 154 
 155 #define _COMPONENT          ACPI_UTILITIES
 156         ACPI_MODULE_NAME    ("utprint")
 157 
 158 
 159 #define ACPI_FORMAT_SIGN            0x01
 160 #define ACPI_FORMAT_SIGN_PLUS       0x02
 161 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
 162 #define ACPI_FORMAT_ZERO            0x08
 163 #define ACPI_FORMAT_LEFT            0x10
 164 #define ACPI_FORMAT_UPPER           0x20
 165 #define ACPI_FORMAT_PREFIX          0x40
 166 
 167 
 168 /* Local prototypes */
 169 
 170 static ACPI_SIZE
 171 AcpiUtBoundStringLength (
 172     const char              *String,
 173     ACPI_SIZE               Count);
 174 
 175 static char *
 176 AcpiUtBoundStringOutput (
 177     char                    *String,
 178     const char              *End,
 179     char                    c);
 180 
 181 static char *
 182 AcpiUtFormatNumber (
 183     char                    *String,
 184     char                    *End,
 185     UINT64                  Number,
 186     UINT8                   Base,
 187     INT32                   Width,
 188     INT32                   Precision,
 189     UINT8                   Type);
 190 
 191 static char *
 192 AcpiUtPutNumber (
 193     char                    *String,
 194     UINT64                  Number,
 195     UINT8                   Base,
 196     BOOLEAN                 Upper);
 197 
 198 
 199 /*******************************************************************************
 200  *
 201  * FUNCTION:    AcpiUtBoundStringLength
 202  *
 203  * PARAMETERS:  String              - String with boundary
 204  *              Count               - Boundary of the string
 205  *
 206  * RETURN:      Length of the string. Less than or equal to Count.
 207  *
 208  * DESCRIPTION: Calculate the length of a string with boundary.
 209  *
 210  ******************************************************************************/
 211 
 212 static ACPI_SIZE
 213 AcpiUtBoundStringLength (
 214     const char              *String,
 215     ACPI_SIZE               Count)
 216 {
 217     UINT32                  Length = 0;
 218 
 219 
 220     while (*String && Count)
 221     {
 222         Length++;
 223         String++;
 224         Count--;
 225     }
 226 
 227     return (Length);
 228 }
 229 
 230 
 231 /*******************************************************************************
 232  *
 233  * FUNCTION:    AcpiUtBoundStringOutput
 234  *
 235  * PARAMETERS:  String              - String with boundary
 236  *              End                 - Boundary of the string
 237  *              c                   - Character to be output to the string
 238  *
 239  * RETURN:      Updated position for next valid character
 240  *
 241  * DESCRIPTION: Output a character into a string with boundary check.
 242  *
 243  ******************************************************************************/
 244 
 245 static char *
 246 AcpiUtBoundStringOutput (
 247     char                    *String,
 248     const char              *End,
 249     char                    c)
 250 {
 251 
 252     if (String < End)
 253     {
 254         *String = c;
 255     }
 256 
 257     ++String;
 258     return (String);
 259 }
 260 
 261 
 262 /*******************************************************************************
 263  *
 264  * FUNCTION:    AcpiUtPutNumber
 265  *
 266  * PARAMETERS:  String              - Buffer to hold reverse-ordered string
 267  *              Number              - Integer to be converted
 268  *              Base                - Base of the integer
 269  *              Upper               - Whether or not using upper cased digits
 270  *
 271  * RETURN:      Updated position for next valid character
 272  *
 273  * DESCRIPTION: Convert an integer into a string, note that, the string holds a
 274  *              reversed ordered number without the trailing zero.
 275  *
 276  ******************************************************************************/
 277 
 278 static char *
 279 AcpiUtPutNumber (
 280     char                    *String,
 281     UINT64                  Number,
 282     UINT8                   Base,
 283     BOOLEAN                 Upper)
 284 {
 285     const char              *Digits;
 286     UINT64                  DigitIndex;
 287     char                    *Pos;
 288 
 289 
 290     Pos = String;
 291     Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits;
 292 
 293     if (Number == 0)
 294     {
 295         *(Pos++) = '0';
 296     }
 297     else
 298     {
 299         while (Number)
 300         {
 301             (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex);
 302             *(Pos++) = Digits[DigitIndex];
 303         }
 304     }
 305 
 306     /* *(Pos++) = '0'; */
 307     return (Pos);
 308 }
 309 
 310 
 311 /*******************************************************************************
 312  *
 313  * FUNCTION:    AcpiUtScanNumber
 314  *
 315  * PARAMETERS:  String              - String buffer
 316  *              NumberPtr           - Where the number is returned
 317  *
 318  * RETURN:      Updated position for next valid character
 319  *
 320  * DESCRIPTION: Scan a string for a decimal integer.
 321  *
 322  ******************************************************************************/
 323 
 324 const char *
 325 AcpiUtScanNumber (
 326     const char              *String,
 327     UINT64                  *NumberPtr)
 328 {
 329     UINT64                  Number = 0;
 330 
 331 
 332     while (isdigit ((int) *String))
 333     {
 334         AcpiUtShortMultiply (Number, 10, &Number);
 335         Number += *(String++) - '0';
 336     }
 337 
 338     *NumberPtr = Number;
 339     return (String);
 340 }
 341 
 342 
 343 /*******************************************************************************
 344  *
 345  * FUNCTION:    AcpiUtPrintNumber
 346  *
 347  * PARAMETERS:  String              - String buffer
 348  *              Number              - The number to be converted
 349  *
 350  * RETURN:      Updated position for next valid character
 351  *
 352  * DESCRIPTION: Print a decimal integer into a string.
 353  *
 354  ******************************************************************************/
 355 
 356 const char *
 357 AcpiUtPrintNumber (
 358     char                    *String,
 359     UINT64                  Number)
 360 {
 361     char                    AsciiString[20];
 362     const char              *Pos1;
 363     char                    *Pos2;
 364 
 365 
 366     Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE);
 367     Pos2 = String;
 368 
 369     while (Pos1 != AsciiString)
 370     {
 371         *(Pos2++) = *(--Pos1);
 372     }
 373 
 374     *Pos2 = 0;
 375     return (String);
 376 }
 377 
 378 
 379 /*******************************************************************************
 380  *
 381  * FUNCTION:    AcpiUtFormatNumber
 382  *
 383  * PARAMETERS:  String              - String buffer with boundary
 384  *              End                 - Boundary of the string
 385  *              Number              - The number to be converted
 386  *              Base                - Base of the integer
 387  *              Width               - Field width
 388  *              Precision           - Precision of the integer
 389  *              Type                - Special printing flags
 390  *
 391  * RETURN:      Updated position for next valid character
 392  *
 393  * DESCRIPTION: Print an integer into a string with any base and any precision.
 394  *
 395  ******************************************************************************/
 396 
 397 static char *
 398 AcpiUtFormatNumber (
 399     char                    *String,
 400     char                    *End,
 401     UINT64                  Number,
 402     UINT8                   Base,
 403     INT32                   Width,
 404     INT32                   Precision,
 405     UINT8                   Type)
 406 {
 407     char                    *Pos;
 408     char                    Sign;
 409     char                    Zero;
 410     BOOLEAN                 NeedPrefix;
 411     BOOLEAN                 Upper;
 412     INT32                   i;
 413     char                    ReversedString[66];
 414 
 415 
 416     /* Parameter validation */
 417 
 418     if (Base < 2 || Base > 16)
 419     {
 420         return (NULL);
 421     }
 422 
 423     if (Type & ACPI_FORMAT_LEFT)
 424     {
 425         Type &= ~ACPI_FORMAT_ZERO;
 426     }
 427 
 428     NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE;
 429     Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
 430     Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' ';
 431 
 432     /* Calculate size according to sign and prefix */
 433 
 434     Sign = '\0';
 435     if (Type & ACPI_FORMAT_SIGN)
 436     {
 437         if ((INT64) Number < 0)
 438         {
 439             Sign = '-';
 440             Number = - (INT64) Number;
 441             Width--;
 442         }
 443         else if (Type & ACPI_FORMAT_SIGN_PLUS)
 444         {
 445             Sign = '+';
 446             Width--;
 447         }
 448         else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE)
 449         {
 450             Sign = ' ';
 451             Width--;
 452         }
 453     }
 454     if (NeedPrefix)
 455     {
 456         Width--;
 457         if (Base == 16)
 458         {
 459             Width--;
 460         }
 461     }
 462 
 463     /* Generate full string in reverse order */
 464 
 465     Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper);
 466     i = (INT32) ACPI_PTR_DIFF (Pos, ReversedString);
 467 
 468     /* Printing 100 using %2d gives "100", not "00" */
 469 
 470     if (i > Precision)
 471     {
 472         Precision = i;
 473     }
 474 
 475     Width -= Precision;
 476 
 477     /* Output the string */
 478 
 479     if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT)))
 480     {
 481         while (--Width >= 0)
 482         {
 483             String = AcpiUtBoundStringOutput (String, End, ' ');
 484         }
 485     }
 486     if (Sign)
 487     {
 488         String = AcpiUtBoundStringOutput (String, End, Sign);
 489     }
 490     if (NeedPrefix)
 491     {
 492         String = AcpiUtBoundStringOutput (String, End, '0');
 493         if (Base == 16)
 494         {
 495             String = AcpiUtBoundStringOutput (
 496                 String, End, Upper ? 'X' : 'x');
 497         }
 498     }
 499     if (!(Type & ACPI_FORMAT_LEFT))
 500     {
 501         while (--Width >= 0)
 502         {
 503             String = AcpiUtBoundStringOutput (String, End, Zero);
 504         }
 505     }
 506 
 507     while (i <= --Precision)
 508     {
 509         String = AcpiUtBoundStringOutput (String, End, '0');
 510     }
 511     while (--i >= 0)
 512     {
 513         String = AcpiUtBoundStringOutput (String, End,
 514                     ReversedString[i]);
 515     }
 516     while (--Width >= 0)
 517     {
 518         String = AcpiUtBoundStringOutput (String, End, ' ');
 519     }
 520 
 521     return (String);
 522 }
 523 
 524 
 525 /*******************************************************************************
 526  *
 527  * FUNCTION:    vsnprintf
 528  *
 529  * PARAMETERS:  String              - String with boundary
 530  *              Size                - Boundary of the string
 531  *              Format              - Standard printf format
 532  *              Args                - Argument list
 533  *
 534  * RETURN:      Number of bytes actually written.
 535  *
 536  * DESCRIPTION: Formatted output to a string using argument list pointer.
 537  *
 538  ******************************************************************************/
 539 
 540 int
 541 vsnprintf (
 542     char                    *String,
 543     ACPI_SIZE               Size,
 544     const char              *Format,
 545     va_list                 Args)
 546 {
 547     UINT8                   Base;
 548     UINT8                   Type;
 549     INT32                   Width;
 550     INT32                   Precision;
 551     char                    Qualifier;
 552     UINT64                  Number;
 553     char                    *Pos;
 554     char                    *End;
 555     char                    c;
 556     const char              *s;
 557     const void              *p;
 558     INT32                   Length;
 559     int                     i;
 560 
 561 
 562     Pos = String;
 563     End = String + Size;
 564 
 565     for (; *Format; ++Format)
 566     {
 567         if (*Format != '%')
 568         {
 569             Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
 570             continue;
 571         }
 572 
 573         Type = 0;
 574         Base = 10;
 575 
 576         /* Process sign */
 577 
 578         do
 579         {
 580             ++Format;
 581             if (*Format == '#')
 582             {
 583                 Type |= ACPI_FORMAT_PREFIX;
 584             }
 585             else if (*Format == '0')
 586             {
 587                 Type |= ACPI_FORMAT_ZERO;
 588             }
 589             else if (*Format == '+')
 590             {
 591                 Type |= ACPI_FORMAT_SIGN_PLUS;
 592             }
 593             else if (*Format == ' ')
 594             {
 595                 Type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
 596             }
 597             else if (*Format == '-')
 598             {
 599                 Type |= ACPI_FORMAT_LEFT;
 600             }
 601             else
 602             {
 603                 break;
 604             }
 605 
 606         } while (1);
 607 
 608         /* Process width */
 609 
 610         Width = -1;
 611         if (isdigit ((int) *Format))
 612         {
 613             Format = AcpiUtScanNumber (Format, &Number);
 614             Width = (INT32) Number;
 615         }
 616         else if (*Format == '*')
 617         {
 618             ++Format;
 619             Width = va_arg (Args, int);
 620             if (Width < 0)
 621             {
 622                 Width = -Width;
 623                 Type |= ACPI_FORMAT_LEFT;
 624             }
 625         }
 626 
 627         /* Process precision */
 628 
 629         Precision = -1;
 630         if (*Format == '.')
 631         {
 632             ++Format;
 633             if (isdigit ((int) *Format))
 634             {
 635                 Format = AcpiUtScanNumber (Format, &Number);
 636                 Precision = (INT32) Number;
 637             }
 638             else if (*Format == '*')
 639             {
 640                 ++Format;
 641                 Precision = va_arg (Args, int);
 642             }
 643 
 644             if (Precision < 0)
 645             {
 646                 Precision = 0;
 647             }
 648         }
 649 
 650         /* Process qualifier */
 651 
 652         Qualifier = -1;
 653         if (*Format == 'h' || *Format == 'l' || *Format == 'L')
 654         {
 655             Qualifier = *Format;
 656             ++Format;
 657 
 658             if (Qualifier == 'l' && *Format == 'l')
 659             {
 660                 Qualifier = 'L';
 661                 ++Format;
 662             }
 663         }
 664 
 665         switch (*Format)
 666         {
 667         case '%':
 668 
 669             Pos = AcpiUtBoundStringOutput (Pos, End, '%');
 670             continue;
 671 
 672         case 'c':
 673 
 674             if (!(Type & ACPI_FORMAT_LEFT))
 675             {
 676                 while (--Width > 0)
 677                 {
 678                     Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
 679                 }
 680             }
 681 
 682             c = (char) va_arg (Args, int);
 683             Pos = AcpiUtBoundStringOutput (Pos, End, c);
 684 
 685             while (--Width > 0)
 686             {
 687                 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
 688             }
 689             continue;
 690 
 691         case 's':
 692 
 693             s = va_arg (Args, char *);
 694             if (!s)
 695             {
 696                 s = "<NULL>";
 697             }
 698             Length = (INT32) AcpiUtBoundStringLength (s, Precision);
 699             if (!(Type & ACPI_FORMAT_LEFT))
 700             {
 701                 while (Length < Width--)
 702                 {
 703                     Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
 704                 }
 705             }
 706 
 707             for (i = 0; i < Length; ++i)
 708             {
 709                 Pos = AcpiUtBoundStringOutput (Pos, End, *s);
 710                 ++s;
 711             }
 712 
 713             while (Length < Width--)
 714             {
 715                 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
 716             }
 717             continue;
 718 
 719         case 'o':
 720 
 721             Base = 8;
 722             break;
 723 
 724         case 'X':
 725 
 726             Type |= ACPI_FORMAT_UPPER;
 727             /* FALLTHROUGH */
 728 
 729         case 'x':
 730 
 731             Base = 16;
 732             break;
 733 
 734         case 'd':
 735         case 'i':
 736 
 737             Type |= ACPI_FORMAT_SIGN;
 738 
 739         case 'u':
 740 
 741             break;
 742 
 743         case 'p':
 744 
 745             if (Width == -1)
 746             {
 747                 Width = 2 * sizeof (void *);
 748                 Type |= ACPI_FORMAT_ZERO;
 749             }
 750 
 751             p = va_arg (Args, void *);
 752             Pos = AcpiUtFormatNumber (
 753                 Pos, End, ACPI_TO_INTEGER (p), 16, Width, Precision, Type);
 754             continue;
 755 
 756         default:
 757 
 758             Pos = AcpiUtBoundStringOutput (Pos, End, '%');
 759             if (*Format)
 760             {
 761                 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
 762             }
 763             else
 764             {
 765                 --Format;
 766             }
 767             continue;
 768         }
 769 
 770         if (Qualifier == 'L')
 771         {
 772             Number = va_arg (Args, UINT64);
 773             if (Type & ACPI_FORMAT_SIGN)
 774             {
 775                 Number = (INT64) Number;
 776             }
 777         }
 778         else if (Qualifier == 'l')
 779         {
 780             Number = va_arg (Args, unsigned long);
 781             if (Type & ACPI_FORMAT_SIGN)
 782             {
 783                 Number = (INT32) Number;
 784             }
 785         }
 786         else if (Qualifier == 'h')
 787         {
 788             Number = (UINT16) va_arg (Args, int);
 789             if (Type & ACPI_FORMAT_SIGN)
 790             {
 791                 Number = (INT16) Number;
 792             }
 793         }
 794         else
 795         {
 796             Number = va_arg (Args, unsigned int);
 797             if (Type & ACPI_FORMAT_SIGN)
 798             {
 799                 Number = (signed int) Number;
 800             }
 801         }
 802 
 803         Pos = AcpiUtFormatNumber (Pos, End, Number, Base,
 804             Width, Precision, Type);
 805     }
 806 
 807     if (Size > 0)
 808     {
 809         if (Pos < End)
 810         {
 811             *Pos = '\0';
 812         }
 813         else
 814         {
 815             End[-1] = '\0';
 816         }
 817     }
 818 
 819     return ((int) ACPI_PTR_DIFF (Pos, String));
 820 }
 821 
 822 
 823 /*******************************************************************************
 824  *
 825  * FUNCTION:    snprintf
 826  *
 827  * PARAMETERS:  String              - String with boundary
 828  *              Size                - Boundary of the string
 829  *              Format, ...         - Standard printf format
 830  *
 831  * RETURN:      Number of bytes actually written.
 832  *
 833  * DESCRIPTION: Formatted output to a string.
 834  *
 835  ******************************************************************************/
 836 
 837 int
 838 snprintf (
 839     char                    *String,
 840     ACPI_SIZE               Size,
 841     const char              *Format,
 842     ...)
 843 {
 844     va_list                 Args;
 845     int                     Length;
 846 
 847 
 848     va_start (Args, Format);
 849     Length = vsnprintf (String, Size, Format, Args);
 850     va_end (Args);
 851 
 852     return (Length);
 853 }
 854 
 855 
 856 /*******************************************************************************
 857  *
 858  * FUNCTION:    sprintf
 859  *
 860  * PARAMETERS:  String              - String with boundary
 861  *              Format, ...         - Standard printf format
 862  *
 863  * RETURN:      Number of bytes actually written.
 864  *
 865  * DESCRIPTION: Formatted output to a string.
 866  *
 867  ******************************************************************************/
 868 
 869 int
 870 sprintf (
 871     char                    *String,
 872     const char              *Format,
 873     ...)
 874 {
 875     va_list                 Args;
 876     int                     Length;
 877 
 878 
 879     va_start (Args, Format);
 880     Length = vsnprintf (String, ACPI_UINT32_MAX, Format, Args);
 881     va_end (Args);
 882 
 883     return (Length);
 884 }
 885 
 886 
 887 #ifdef ACPI_APPLICATION
 888 /*******************************************************************************
 889  *
 890  * FUNCTION:    vprintf
 891  *
 892  * PARAMETERS:  Format              - Standard printf format
 893  *              Args                - Argument list
 894  *
 895  * RETURN:      Number of bytes actually written.
 896  *
 897  * DESCRIPTION: Formatted output to stdout using argument list pointer.
 898  *
 899  ******************************************************************************/
 900 
 901 int
 902 vprintf (
 903     const char              *Format,
 904     va_list                 Args)
 905 {
 906     ACPI_CPU_FLAGS          Flags;
 907     int                     Length;
 908 
 909 
 910     Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
 911     Length = vsnprintf (AcpiGbl_PrintBuffer,
 912                 sizeof (AcpiGbl_PrintBuffer), Format, Args);
 913 
 914     (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, ACPI_FILE_OUT);
 915     AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
 916 
 917     return (Length);
 918 }
 919 
 920 
 921 /*******************************************************************************
 922  *
 923  * FUNCTION:    printf
 924  *
 925  * PARAMETERS:  Format, ...         - Standard printf format
 926  *
 927  * RETURN:      Number of bytes actually written.
 928  *
 929  * DESCRIPTION: Formatted output to stdout.
 930  *
 931  ******************************************************************************/
 932 
 933 int
 934 printf (
 935     const char              *Format,
 936     ...)
 937 {
 938     va_list                 Args;
 939     int                     Length;
 940 
 941 
 942     va_start (Args, Format);
 943     Length = vprintf (Format, Args);
 944     va_end (Args);
 945 
 946     return (Length);
 947 }
 948 
 949 
 950 /*******************************************************************************
 951  *
 952  * FUNCTION:    vfprintf
 953  *
 954  * PARAMETERS:  File                - File descriptor
 955  *              Format              - Standard printf format
 956  *              Args                - Argument list
 957  *
 958  * RETURN:      Number of bytes actually written.
 959  *
 960  * DESCRIPTION: Formatted output to a file using argument list pointer.
 961  *
 962  ******************************************************************************/
 963 
 964 int
 965 vfprintf (
 966     FILE                    *File,
 967     const char              *Format,
 968     va_list                 Args)
 969 {
 970     ACPI_CPU_FLAGS          Flags;
 971     int                     Length;
 972 
 973 
 974     Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
 975     Length = vsnprintf (AcpiGbl_PrintBuffer,
 976         sizeof (AcpiGbl_PrintBuffer), Format, Args);
 977 
 978     (void) fwrite (AcpiGbl_PrintBuffer, Length, 1, File);
 979     AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
 980 
 981     return (Length);
 982 }
 983 
 984 
 985 /*******************************************************************************
 986  *
 987  * FUNCTION:    fprintf
 988  *
 989  * PARAMETERS:  File                - File descriptor
 990  *              Format, ...         - Standard printf format
 991  *
 992  * RETURN:      Number of bytes actually written.
 993  *
 994  * DESCRIPTION: Formatted output to a file.
 995  *
 996  ******************************************************************************/
 997 
 998 int
 999 fprintf (
1000     FILE                    *File,
1001     const char              *Format,
1002     ...)
1003 {
1004     va_list                 Args;
1005     int                     Length;
1006 
1007 
1008     va_start (Args, Format);
1009     Length = vfprintf (File, Format, Args);
1010     va_end (Args);
1011 
1012     return (Length);
1013 }
1014 #endif