Home | History | Annotate | Line # | Download | only in lib
      1  1.5  jmcneill /*	$NetBSD: print.c,v 1.5 2021/09/30 19:02:48 jmcneill Exp $	*/
      2  1.1  jakllsch 
      3  1.1  jakllsch /*++
      4  1.1  jakllsch 
      5  1.1  jakllsch Copyright (c) 1998  Intel Corporation
      6  1.1  jakllsch 
      7  1.1  jakllsch Module Name:
      8  1.1  jakllsch 
      9  1.1  jakllsch     print.c
     10  1.1  jakllsch 
     11  1.1  jakllsch Abstract:
     12  1.1  jakllsch 
     13  1.1  jakllsch 
     14  1.1  jakllsch 
     15  1.1  jakllsch 
     16  1.1  jakllsch Revision History
     17  1.1  jakllsch 
     18  1.1  jakllsch --*/
     19  1.1  jakllsch 
     20  1.1  jakllsch #include "lib.h"
     21  1.1  jakllsch #include "efistdarg.h"                        // !!!
     22  1.1  jakllsch 
     23  1.1  jakllsch //
     24  1.1  jakllsch // Declare runtime functions
     25  1.1  jakllsch //
     26  1.1  jakllsch 
     27  1.1  jakllsch #ifdef RUNTIME_CODE
     28  1.1  jakllsch #ifndef __GNUC__
     29  1.1  jakllsch #pragma RUNTIME_CODE(DbgPrint)
     30  1.1  jakllsch 
     31  1.1  jakllsch // For debugging..
     32  1.1  jakllsch 
     33  1.1  jakllsch /*
     34  1.1  jakllsch #pragma RUNTIME_CODE(_Print)
     35  1.1  jakllsch #pragma RUNTIME_CODE(PFLUSH)
     36  1.1  jakllsch #pragma RUNTIME_CODE(PSETATTR)
     37  1.1  jakllsch #pragma RUNTIME_CODE(PPUTC)
     38  1.1  jakllsch #pragma RUNTIME_CODE(PGETC)
     39  1.1  jakllsch #pragma RUNTIME_CODE(PITEM)
     40  1.1  jakllsch #pragma RUNTIME_CODE(ValueToHex)
     41  1.1  jakllsch #pragma RUNTIME_CODE(ValueToString)
     42  1.1  jakllsch #pragma RUNTIME_CODE(TimeToString)
     43  1.1  jakllsch */
     44  1.1  jakllsch 
     45  1.1  jakllsch #endif /* !defined(__GNUC__) */
     46  1.1  jakllsch #endif
     47  1.1  jakllsch 
     48  1.1  jakllsch //
     49  1.1  jakllsch //
     50  1.1  jakllsch //
     51  1.1  jakllsch 
     52  1.1  jakllsch 
     53  1.1  jakllsch #define PRINT_STRING_LEN            200
     54  1.1  jakllsch #define PRINT_ITEM_BUFFER_LEN       100
     55  1.1  jakllsch 
     56  1.1  jakllsch typedef struct {
     57  1.1  jakllsch     BOOLEAN             Ascii;
     58  1.1  jakllsch     UINTN               Index;
     59  1.1  jakllsch     union {
     60  1.2  jmcneill         CONST CHAR16    *pw;
     61  1.2  jmcneill         CONST CHAR8     *pc;
     62  1.1  jakllsch     } un;
     63  1.1  jakllsch } POINTER;
     64  1.1  jakllsch 
     65  1.1  jakllsch #define pw	un.pw
     66  1.1  jakllsch #define pc	un.pc
     67  1.1  jakllsch 
     68  1.1  jakllsch typedef struct _pitem {
     69  1.1  jakllsch 
     70  1.1  jakllsch     POINTER     Item;
     71  1.1  jakllsch     CHAR16      Scratch[PRINT_ITEM_BUFFER_LEN];
     72  1.1  jakllsch     UINTN       Width;
     73  1.1  jakllsch     UINTN       FieldWidth;
     74  1.1  jakllsch     UINTN       *WidthParse;
     75  1.1  jakllsch     CHAR16      Pad;
     76  1.1  jakllsch     BOOLEAN     PadBefore;
     77  1.1  jakllsch     BOOLEAN     Comma;
     78  1.1  jakllsch     BOOLEAN     Long;
     79  1.1  jakllsch } PRINT_ITEM;
     80  1.1  jakllsch 
     81  1.1  jakllsch 
     82  1.1  jakllsch typedef struct _pstate {
     83  1.1  jakllsch     // Input
     84  1.1  jakllsch     POINTER     fmt;
     85  1.1  jakllsch     va_list     args;
     86  1.1  jakllsch 
     87  1.1  jakllsch     // Output
     88  1.1  jakllsch     CHAR16      *Buffer;
     89  1.1  jakllsch     CHAR16      *End;
     90  1.1  jakllsch     CHAR16      *Pos;
     91  1.1  jakllsch     UINTN       Len;
     92  1.1  jakllsch 
     93  1.2  jmcneill     UINTN       Attr;
     94  1.1  jakllsch     UINTN       RestoreAttr;
     95  1.1  jakllsch 
     96  1.1  jakllsch     UINTN       AttrNorm;
     97  1.1  jakllsch     UINTN       AttrHighlight;
     98  1.1  jakllsch     UINTN       AttrError;
     99  1.1  jakllsch 
    100  1.2  jmcneill     INTN        (EFIAPI *Output)(VOID *context, CHAR16 *str);
    101  1.2  jmcneill     INTN        (EFIAPI *SetAttr)(VOID *context, UINTN attr);
    102  1.2  jmcneill     VOID        *Context;
    103  1.1  jakllsch 
    104  1.1  jakllsch     // Current item being formatted
    105  1.1  jakllsch     struct _pitem  *Item;
    106  1.1  jakllsch } PRINT_STATE;
    107  1.1  jakllsch 
    108  1.1  jakllsch //
    109  1.1  jakllsch // Internal fucntions
    110  1.1  jakllsch //
    111  1.1  jakllsch 
    112  1.1  jakllsch STATIC
    113  1.1  jakllsch UINTN
    114  1.1  jakllsch _Print (
    115  1.1  jakllsch     IN PRINT_STATE     *ps
    116  1.1  jakllsch     );
    117  1.1  jakllsch 
    118  1.1  jakllsch STATIC
    119  1.1  jakllsch UINTN
    120  1.1  jakllsch _IPrint (
    121  1.1  jakllsch     IN UINTN                            Column,
    122  1.1  jakllsch     IN UINTN                            Row,
    123  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE     *Out,
    124  1.2  jmcneill     IN CONST CHAR16                     *fmt,
    125  1.2  jmcneill     IN CONST CHAR8                      *fmta,
    126  1.1  jakllsch     IN va_list                          args
    127  1.1  jakllsch     );
    128  1.1  jakllsch 
    129  1.1  jakllsch STATIC
    130  1.1  jakllsch INTN EFIAPI
    131  1.1  jakllsch _DbgOut (
    132  1.1  jakllsch     IN VOID     *Context,
    133  1.1  jakllsch     IN CHAR16   *Buffer
    134  1.1  jakllsch     );
    135  1.1  jakllsch 
    136  1.1  jakllsch STATIC
    137  1.1  jakllsch VOID
    138  1.1  jakllsch PFLUSH (
    139  1.1  jakllsch     IN OUT PRINT_STATE     *ps
    140  1.1  jakllsch     );
    141  1.1  jakllsch 
    142  1.1  jakllsch STATIC
    143  1.1  jakllsch VOID
    144  1.1  jakllsch PPUTC (
    145  1.1  jakllsch     IN OUT PRINT_STATE     *ps,
    146  1.1  jakllsch     IN CHAR16              c
    147  1.1  jakllsch     );
    148  1.1  jakllsch 
    149  1.1  jakllsch STATIC
    150  1.1  jakllsch VOID
    151  1.1  jakllsch PITEM (
    152  1.1  jakllsch     IN OUT PRINT_STATE  *ps
    153  1.1  jakllsch     );
    154  1.1  jakllsch 
    155  1.1  jakllsch STATIC
    156  1.1  jakllsch CHAR16
    157  1.1  jakllsch PGETC (
    158  1.1  jakllsch     IN POINTER      *p
    159  1.1  jakllsch     );
    160  1.1  jakllsch 
    161  1.1  jakllsch STATIC
    162  1.1  jakllsch VOID
    163  1.1  jakllsch PSETATTR (
    164  1.1  jakllsch     IN OUT PRINT_STATE  *ps,
    165  1.1  jakllsch     IN UINTN             Attr
    166  1.1  jakllsch     );
    167  1.1  jakllsch 
    168  1.1  jakllsch //
    169  1.1  jakllsch //
    170  1.1  jakllsch //
    171  1.1  jakllsch 
    172  1.1  jakllsch INTN EFIAPI
    173  1.1  jakllsch _SPrint (
    174  1.1  jakllsch     IN VOID     *Context,
    175  1.1  jakllsch     IN CHAR16   *Buffer
    176  1.1  jakllsch     );
    177  1.1  jakllsch 
    178  1.1  jakllsch INTN EFIAPI
    179  1.1  jakllsch _PoolPrint (
    180  1.1  jakllsch     IN VOID     *Context,
    181  1.1  jakllsch     IN CHAR16   *Buffer
    182  1.1  jakllsch     );
    183  1.1  jakllsch 
    184  1.1  jakllsch INTN
    185  1.1  jakllsch DbgPrint (
    186  1.2  jmcneill     IN INTN         mask,
    187  1.2  jmcneill     IN CONST CHAR8  *fmt,
    188  1.1  jakllsch     ...
    189  1.1  jakllsch     )
    190  1.1  jakllsch /*++
    191  1.1  jakllsch 
    192  1.1  jakllsch Routine Description:
    193  1.1  jakllsch 
    194  1.1  jakllsch     Prints a formatted unicode string to the default StandardError console
    195  1.1  jakllsch 
    196  1.1  jakllsch Arguments:
    197  1.1  jakllsch 
    198  1.1  jakllsch     mask        - Bit mask of debug string.  If a bit is set in the
    199  1.2  jmcneill                   mask that is also set in EFIDebug the string is
    200  1.1  jakllsch                   printed; otherwise, the string is not printed
    201  1.1  jakllsch 
    202  1.1  jakllsch     fmt         - Format string
    203  1.1  jakllsch 
    204  1.1  jakllsch Returns:
    205  1.1  jakllsch 
    206  1.1  jakllsch     Length of string printed to the StandardError console
    207  1.1  jakllsch 
    208  1.1  jakllsch --*/
    209  1.1  jakllsch {
    210  1.1  jakllsch     SIMPLE_TEXT_OUTPUT_INTERFACE    *DbgOut;
    211  1.1  jakllsch     PRINT_STATE     ps;
    212  1.1  jakllsch     va_list         args;
    213  1.1  jakllsch     UINTN           back;
    214  1.1  jakllsch     UINTN           attr;
    215  1.1  jakllsch     UINTN           SavedAttribute;
    216  1.1  jakllsch 
    217  1.1  jakllsch 
    218  1.1  jakllsch     if (!(EFIDebug & mask)) {
    219  1.1  jakllsch         return 0;
    220  1.1  jakllsch     }
    221  1.1  jakllsch 
    222  1.1  jakllsch     va_start (args, fmt);
    223  1.1  jakllsch     ZeroMem (&ps, sizeof(ps));
    224  1.1  jakllsch 
    225  1.2  jmcneill     ps.Output = _DbgOut;
    226  1.1  jakllsch     ps.fmt.Ascii = TRUE;
    227  1.1  jakllsch     ps.fmt.pc = fmt;
    228  1.1  jakllsch     va_copy(ps.args, args);
    229  1.2  jmcneill     ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED);
    230  1.1  jakllsch 
    231  1.1  jakllsch     DbgOut = LibRuntimeDebugOut;
    232  1.1  jakllsch 
    233  1.1  jakllsch     if (!DbgOut) {
    234  1.1  jakllsch         DbgOut = ST->StdErr;
    235  1.1  jakllsch     }
    236  1.1  jakllsch 
    237  1.1  jakllsch     if (DbgOut) {
    238  1.1  jakllsch         ps.Attr = DbgOut->Mode->Attribute;
    239  1.1  jakllsch         ps.Context = DbgOut;
    240  1.2  jmcneill         ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN))  DbgOut->SetAttribute;
    241  1.1  jakllsch     }
    242  1.1  jakllsch 
    243  1.1  jakllsch     SavedAttribute = ps.Attr;
    244  1.1  jakllsch 
    245  1.1  jakllsch     back = (ps.Attr >> 4) & 0xf;
    246  1.1  jakllsch     ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
    247  1.1  jakllsch     ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
    248  1.1  jakllsch     ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
    249  1.1  jakllsch 
    250  1.1  jakllsch     attr = ps.AttrNorm;
    251  1.1  jakllsch 
    252  1.1  jakllsch     if (mask & D_WARN) {
    253  1.1  jakllsch         attr = ps.AttrHighlight;
    254  1.1  jakllsch     }
    255  1.1  jakllsch 
    256  1.1  jakllsch     if (mask & D_ERROR) {
    257  1.1  jakllsch         attr = ps.AttrError;
    258  1.1  jakllsch     }
    259  1.1  jakllsch 
    260  1.1  jakllsch     if (ps.SetAttr) {
    261  1.1  jakllsch         ps.Attr = attr;
    262  1.2  jmcneill         uefi_call_wrapper(ps.SetAttr, 2, ps.Context, attr);
    263  1.1  jakllsch     }
    264  1.1  jakllsch 
    265  1.1  jakllsch     _Print (&ps);
    266  1.1  jakllsch 
    267  1.1  jakllsch     va_end (ps.args);
    268  1.1  jakllsch     va_end (args);
    269  1.1  jakllsch 
    270  1.1  jakllsch     //
    271  1.1  jakllsch     // Restore original attributes
    272  1.1  jakllsch     //
    273  1.1  jakllsch 
    274  1.1  jakllsch     if (ps.SetAttr) {
    275  1.2  jmcneill         uefi_call_wrapper(ps.SetAttr, 2, ps.Context, SavedAttribute);
    276  1.1  jakllsch     }
    277  1.2  jmcneill 
    278  1.1  jakllsch     return 0;
    279  1.1  jakllsch }
    280  1.1  jakllsch 
    281  1.1  jakllsch STATIC
    282  1.1  jakllsch INTN
    283  1.1  jakllsch IsLocalPrint(void *func)
    284  1.1  jakllsch {
    285  1.1  jakllsch 	if (func == _DbgOut || func == _SPrint || func == _PoolPrint)
    286  1.1  jakllsch 		return 1;
    287  1.1  jakllsch 	return 0;
    288  1.1  jakllsch }
    289  1.1  jakllsch 
    290  1.1  jakllsch STATIC
    291  1.1  jakllsch INTN EFIAPI
    292  1.1  jakllsch _DbgOut (
    293  1.1  jakllsch     IN VOID     *Context,
    294  1.1  jakllsch     IN CHAR16   *Buffer
    295  1.1  jakllsch     )
    296  1.1  jakllsch // Append string worker for DbgPrint
    297  1.1  jakllsch {
    298  1.1  jakllsch     SIMPLE_TEXT_OUTPUT_INTERFACE    *DbgOut;
    299  1.1  jakllsch 
    300  1.1  jakllsch     DbgOut = Context;
    301  1.1  jakllsch //    if (!DbgOut && ST && ST->ConOut) {
    302  1.1  jakllsch //        DbgOut = ST->ConOut;
    303  1.1  jakllsch //    }
    304  1.1  jakllsch 
    305  1.1  jakllsch     if (DbgOut) {
    306  1.1  jakllsch 	if (IsLocalPrint(DbgOut->OutputString))
    307  1.1  jakllsch 		DbgOut->OutputString(DbgOut, Buffer);
    308  1.1  jakllsch         else
    309  1.1  jakllsch 		uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer);
    310  1.1  jakllsch     }
    311  1.1  jakllsch 
    312  1.1  jakllsch     return 0;
    313  1.1  jakllsch }
    314  1.1  jakllsch 
    315  1.1  jakllsch INTN EFIAPI
    316  1.1  jakllsch _SPrint (
    317  1.1  jakllsch     IN VOID     *Context,
    318  1.1  jakllsch     IN CHAR16   *Buffer
    319  1.1  jakllsch     )
    320  1.5  jmcneill // Append string worker for UnicodeSPrint, PoolPrint and CatPrint
    321  1.1  jakllsch {
    322  1.1  jakllsch     UINTN           len;
    323  1.1  jakllsch     POOL_PRINT      *spc;
    324  1.1  jakllsch 
    325  1.1  jakllsch     spc = Context;
    326  1.1  jakllsch     len = StrLen(Buffer);
    327  1.1  jakllsch 
    328  1.1  jakllsch     //
    329  1.1  jakllsch     // Is the string is over the max truncate it
    330  1.1  jakllsch     //
    331  1.1  jakllsch 
    332  1.1  jakllsch     if (spc->len + len > spc->maxlen) {
    333  1.1  jakllsch         len = spc->maxlen - spc->len;
    334  1.1  jakllsch     }
    335  1.1  jakllsch 
    336  1.1  jakllsch     //
    337  1.1  jakllsch     // Append the new text
    338  1.1  jakllsch     //
    339  1.1  jakllsch 
    340  1.1  jakllsch     CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16));
    341  1.1  jakllsch     spc->len += len;
    342  1.1  jakllsch 
    343  1.1  jakllsch     //
    344  1.1  jakllsch     // Null terminate it
    345  1.1  jakllsch     //
    346  1.1  jakllsch 
    347  1.1  jakllsch     if (spc->len < spc->maxlen) {
    348  1.1  jakllsch         spc->str[spc->len] = 0;
    349  1.1  jakllsch     } else if (spc->maxlen) {
    350  1.2  jmcneill         spc->str[spc->maxlen] = 0;
    351  1.1  jakllsch     }
    352  1.1  jakllsch 
    353  1.1  jakllsch     return 0;
    354  1.1  jakllsch }
    355  1.1  jakllsch 
    356  1.1  jakllsch 
    357  1.1  jakllsch INTN EFIAPI
    358  1.1  jakllsch _PoolPrint (
    359  1.1  jakllsch     IN VOID     *Context,
    360  1.1  jakllsch     IN CHAR16   *Buffer
    361  1.1  jakllsch     )
    362  1.1  jakllsch // Append string worker for PoolPrint and CatPrint
    363  1.1  jakllsch {
    364  1.1  jakllsch     UINTN           newlen;
    365  1.1  jakllsch     POOL_PRINT      *spc;
    366  1.1  jakllsch 
    367  1.1  jakllsch     spc = Context;
    368  1.1  jakllsch     newlen = spc->len + StrLen(Buffer) + 1;
    369  1.1  jakllsch 
    370  1.1  jakllsch     //
    371  1.1  jakllsch     // Is the string is over the max, grow the buffer
    372  1.1  jakllsch     //
    373  1.1  jakllsch 
    374  1.1  jakllsch     if (newlen > spc->maxlen) {
    375  1.1  jakllsch 
    376  1.1  jakllsch         //
    377  1.1  jakllsch         // Grow the pool buffer
    378  1.1  jakllsch         //
    379  1.1  jakllsch 
    380  1.1  jakllsch         newlen += PRINT_STRING_LEN;
    381  1.1  jakllsch         spc->maxlen = newlen;
    382  1.1  jakllsch         spc->str = ReallocatePool (
    383  1.2  jmcneill                         spc->str,
    384  1.2  jmcneill                         spc->len * sizeof(CHAR16),
    385  1.1  jakllsch                         spc->maxlen * sizeof(CHAR16)
    386  1.1  jakllsch                         );
    387  1.1  jakllsch 
    388  1.1  jakllsch         if (!spc->str) {
    389  1.1  jakllsch             spc->len = 0;
    390  1.1  jakllsch             spc->maxlen = 0;
    391  1.1  jakllsch         }
    392  1.1  jakllsch     }
    393  1.1  jakllsch 
    394  1.1  jakllsch     //
    395  1.1  jakllsch     // Append the new text
    396  1.1  jakllsch     //
    397  1.1  jakllsch 
    398  1.1  jakllsch     return _SPrint (Context, Buffer);
    399  1.1  jakllsch }
    400  1.1  jakllsch 
    401  1.1  jakllsch 
    402  1.1  jakllsch 
    403  1.1  jakllsch VOID
    404  1.1  jakllsch _PoolCatPrint (
    405  1.2  jmcneill     IN CONST CHAR16     *fmt,
    406  1.1  jakllsch     IN va_list          args,
    407  1.1  jakllsch     IN OUT POOL_PRINT   *spc,
    408  1.2  jmcneill     IN INTN             (EFIAPI *Output)(VOID *context, CHAR16 *str)
    409  1.1  jakllsch     )
    410  1.5  jmcneill // Dispatch function for UnicodeSPrint, PoolPrint, and CatPrint
    411  1.1  jakllsch {
    412  1.1  jakllsch     PRINT_STATE         ps;
    413  1.1  jakllsch 
    414  1.1  jakllsch     ZeroMem (&ps, sizeof(ps));
    415  1.1  jakllsch     ps.Output  = Output;
    416  1.1  jakllsch     ps.Context = spc;
    417  1.1  jakllsch     ps.fmt.pw = fmt;
    418  1.1  jakllsch     va_copy(ps.args, args);
    419  1.1  jakllsch     _Print (&ps);
    420  1.1  jakllsch     va_end(ps.args);
    421  1.1  jakllsch }
    422  1.1  jakllsch 
    423  1.1  jakllsch 
    424  1.1  jakllsch 
    425  1.1  jakllsch UINTN
    426  1.5  jmcneill UnicodeVSPrint (
    427  1.2  jmcneill     OUT CHAR16        *Str,
    428  1.2  jmcneill     IN UINTN          StrSize,
    429  1.2  jmcneill     IN CONST CHAR16   *fmt,
    430  1.2  jmcneill     va_list           args
    431  1.1  jakllsch     )
    432  1.1  jakllsch /*++
    433  1.1  jakllsch 
    434  1.1  jakllsch Routine Description:
    435  1.1  jakllsch 
    436  1.2  jmcneill     Prints a formatted unicode string to a buffer using a va_list
    437  1.1  jakllsch 
    438  1.1  jakllsch Arguments:
    439  1.1  jakllsch 
    440  1.1  jakllsch     Str         - Output buffer to print the formatted string into
    441  1.1  jakllsch 
    442  1.1  jakllsch     StrSize     - Size of Str.  String is truncated to this size.
    443  1.1  jakllsch                   A size of 0 means there is no limit
    444  1.1  jakllsch 
    445  1.1  jakllsch     fmt         - The format string
    446  1.1  jakllsch 
    447  1.2  jmcneill     args        - va_list
    448  1.2  jmcneill 
    449  1.2  jmcneill 
    450  1.1  jakllsch Returns:
    451  1.1  jakllsch 
    452  1.1  jakllsch     String length returned in buffer
    453  1.1  jakllsch 
    454  1.1  jakllsch --*/
    455  1.1  jakllsch {
    456  1.1  jakllsch     POOL_PRINT          spc;
    457  1.1  jakllsch 
    458  1.1  jakllsch     spc.str    = Str;
    459  1.1  jakllsch     spc.maxlen = StrSize / sizeof(CHAR16) - 1;
    460  1.1  jakllsch     spc.len    = 0;
    461  1.1  jakllsch 
    462  1.1  jakllsch     _PoolCatPrint (fmt, args, &spc, _SPrint);
    463  1.2  jmcneill 
    464  1.2  jmcneill     return spc.len;
    465  1.2  jmcneill }
    466  1.2  jmcneill 
    467  1.2  jmcneill UINTN
    468  1.5  jmcneill UnicodeSPrint (
    469  1.2  jmcneill     OUT CHAR16        *Str,
    470  1.2  jmcneill     IN UINTN          StrSize,
    471  1.2  jmcneill     IN CONST CHAR16   *fmt,
    472  1.2  jmcneill     ...
    473  1.2  jmcneill     )
    474  1.2  jmcneill /*++
    475  1.2  jmcneill 
    476  1.2  jmcneill Routine Description:
    477  1.2  jmcneill 
    478  1.2  jmcneill     Prints a formatted unicode string to a buffer
    479  1.2  jmcneill 
    480  1.2  jmcneill Arguments:
    481  1.2  jmcneill 
    482  1.2  jmcneill     Str         - Output buffer to print the formatted string into
    483  1.2  jmcneill 
    484  1.2  jmcneill     StrSize     - Size of Str.  String is truncated to this size.
    485  1.2  jmcneill                   A size of 0 means there is no limit
    486  1.2  jmcneill 
    487  1.2  jmcneill     fmt         - The format string
    488  1.2  jmcneill 
    489  1.2  jmcneill Returns:
    490  1.2  jmcneill 
    491  1.2  jmcneill     String length returned in buffer
    492  1.2  jmcneill 
    493  1.2  jmcneill --*/
    494  1.2  jmcneill {
    495  1.2  jmcneill     va_list          args;
    496  1.2  jmcneill     UINTN            len;
    497  1.2  jmcneill 
    498  1.2  jmcneill     va_start (args, fmt);
    499  1.5  jmcneill     len = UnicodeVSPrint(Str, StrSize, fmt, args);
    500  1.1  jakllsch     va_end (args);
    501  1.2  jmcneill 
    502  1.2  jmcneill     return len;
    503  1.1  jakllsch }
    504  1.1  jakllsch 
    505  1.2  jmcneill CHAR16 *
    506  1.2  jmcneill VPoolPrint (
    507  1.2  jmcneill     IN CONST CHAR16     *fmt,
    508  1.2  jmcneill     va_list             args
    509  1.2  jmcneill     )
    510  1.2  jmcneill /*++
    511  1.2  jmcneill 
    512  1.2  jmcneill Routine Description:
    513  1.2  jmcneill 
    514  1.2  jmcneill     Prints a formatted unicode string to allocated pool using va_list argument.
    515  1.2  jmcneill     The caller must free the resulting buffer.
    516  1.2  jmcneill 
    517  1.2  jmcneill Arguments:
    518  1.2  jmcneill 
    519  1.2  jmcneill     fmt         - The format string
    520  1.2  jmcneill     args        - The arguments in va_list form
    521  1.2  jmcneill 
    522  1.2  jmcneill Returns:
    523  1.2  jmcneill 
    524  1.2  jmcneill     Allocated buffer with the formatted string printed in it.
    525  1.2  jmcneill     The caller must free the allocated buffer.   The buffer
    526  1.2  jmcneill     allocation is not packed.
    527  1.2  jmcneill 
    528  1.2  jmcneill --*/
    529  1.2  jmcneill {
    530  1.2  jmcneill     POOL_PRINT          spc;
    531  1.2  jmcneill     ZeroMem (&spc, sizeof(spc));
    532  1.2  jmcneill     _PoolCatPrint (fmt, args, &spc, _PoolPrint);
    533  1.2  jmcneill     return spc.str;
    534  1.2  jmcneill }
    535  1.1  jakllsch 
    536  1.1  jakllsch CHAR16 *
    537  1.1  jakllsch PoolPrint (
    538  1.2  jmcneill     IN CONST CHAR16     *fmt,
    539  1.1  jakllsch     ...
    540  1.1  jakllsch     )
    541  1.1  jakllsch /*++
    542  1.1  jakllsch 
    543  1.1  jakllsch Routine Description:
    544  1.1  jakllsch 
    545  1.1  jakllsch     Prints a formatted unicode string to allocated pool.  The caller
    546  1.1  jakllsch     must free the resulting buffer.
    547  1.1  jakllsch 
    548  1.1  jakllsch Arguments:
    549  1.1  jakllsch 
    550  1.1  jakllsch     fmt         - The format string
    551  1.1  jakllsch 
    552  1.1  jakllsch Returns:
    553  1.1  jakllsch 
    554  1.2  jmcneill     Allocated buffer with the formatted string printed in it.
    555  1.1  jakllsch     The caller must free the allocated buffer.   The buffer
    556  1.1  jakllsch     allocation is not packed.
    557  1.1  jakllsch 
    558  1.1  jakllsch --*/
    559  1.1  jakllsch {
    560  1.2  jmcneill     va_list args;
    561  1.2  jmcneill     CHAR16 *pool;
    562  1.1  jakllsch     va_start (args, fmt);
    563  1.2  jmcneill     pool = VPoolPrint(fmt, args);
    564  1.1  jakllsch     va_end (args);
    565  1.2  jmcneill     return pool;
    566  1.1  jakllsch }
    567  1.1  jakllsch 
    568  1.1  jakllsch CHAR16 *
    569  1.1  jakllsch CatPrint (
    570  1.1  jakllsch     IN OUT POOL_PRINT   *Str,
    571  1.2  jmcneill     IN CONST CHAR16     *fmt,
    572  1.1  jakllsch     ...
    573  1.1  jakllsch     )
    574  1.1  jakllsch /*++
    575  1.1  jakllsch 
    576  1.1  jakllsch Routine Description:
    577  1.1  jakllsch 
    578  1.2  jmcneill     Concatenates a formatted unicode string to allocated pool.
    579  1.1  jakllsch     The caller must free the resulting buffer.
    580  1.1  jakllsch 
    581  1.1  jakllsch Arguments:
    582  1.1  jakllsch 
    583  1.2  jmcneill     Str         - Tracks the allocated pool, size in use, and
    584  1.1  jakllsch                   amount of pool allocated.
    585  1.1  jakllsch 
    586  1.1  jakllsch     fmt         - The format string
    587  1.1  jakllsch 
    588  1.1  jakllsch Returns:
    589  1.1  jakllsch 
    590  1.2  jmcneill     Allocated buffer with the formatted string printed in it.
    591  1.1  jakllsch     The caller must free the allocated buffer.   The buffer
    592  1.1  jakllsch     allocation is not packed.
    593  1.1  jakllsch 
    594  1.1  jakllsch --*/
    595  1.1  jakllsch {
    596  1.1  jakllsch     va_list             args;
    597  1.1  jakllsch 
    598  1.1  jakllsch     va_start (args, fmt);
    599  1.1  jakllsch     _PoolCatPrint (fmt, args, Str, _PoolPrint);
    600  1.1  jakllsch     va_end (args);
    601  1.1  jakllsch     return Str->str;
    602  1.1  jakllsch }
    603  1.1  jakllsch 
    604  1.1  jakllsch 
    605  1.1  jakllsch 
    606  1.1  jakllsch UINTN
    607  1.1  jakllsch Print (
    608  1.2  jmcneill     IN CONST CHAR16   *fmt,
    609  1.1  jakllsch     ...
    610  1.1  jakllsch     )
    611  1.1  jakllsch /*++
    612  1.1  jakllsch 
    613  1.1  jakllsch Routine Description:
    614  1.1  jakllsch 
    615  1.1  jakllsch     Prints a formatted unicode string to the default console
    616  1.1  jakllsch 
    617  1.1  jakllsch Arguments:
    618  1.1  jakllsch 
    619  1.1  jakllsch     fmt         - Format string
    620  1.1  jakllsch 
    621  1.1  jakllsch Returns:
    622  1.1  jakllsch 
    623  1.1  jakllsch     Length of string printed to the console
    624  1.1  jakllsch 
    625  1.1  jakllsch --*/
    626  1.1  jakllsch {
    627  1.1  jakllsch     va_list     args;
    628  1.1  jakllsch     UINTN       back;
    629  1.1  jakllsch 
    630  1.1  jakllsch     va_start (args, fmt);
    631  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
    632  1.1  jakllsch     va_end (args);
    633  1.1  jakllsch     return back;
    634  1.1  jakllsch }
    635  1.1  jakllsch 
    636  1.1  jakllsch UINTN
    637  1.1  jakllsch VPrint (
    638  1.2  jmcneill     IN CONST CHAR16   *fmt,
    639  1.2  jmcneill     va_list           args
    640  1.1  jakllsch     )
    641  1.1  jakllsch /*++
    642  1.1  jakllsch 
    643  1.1  jakllsch Routine Description:
    644  1.1  jakllsch 
    645  1.1  jakllsch     Prints a formatted unicode string to the default console using a va_list
    646  1.1  jakllsch 
    647  1.1  jakllsch Arguments:
    648  1.1  jakllsch 
    649  1.1  jakllsch     fmt         - Format string
    650  1.1  jakllsch     args        - va_list
    651  1.1  jakllsch Returns:
    652  1.1  jakllsch 
    653  1.1  jakllsch     Length of string printed to the console
    654  1.1  jakllsch 
    655  1.1  jakllsch --*/
    656  1.1  jakllsch {
    657  1.1  jakllsch     return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
    658  1.1  jakllsch }
    659  1.1  jakllsch 
    660  1.1  jakllsch 
    661  1.1  jakllsch UINTN
    662  1.1  jakllsch PrintAt (
    663  1.2  jmcneill     IN UINTN          Column,
    664  1.2  jmcneill     IN UINTN          Row,
    665  1.2  jmcneill     IN CONST CHAR16   *fmt,
    666  1.1  jakllsch     ...
    667  1.1  jakllsch     )
    668  1.1  jakllsch /*++
    669  1.1  jakllsch 
    670  1.1  jakllsch Routine Description:
    671  1.1  jakllsch 
    672  1.2  jmcneill     Prints a formatted unicode string to the default console, at
    673  1.1  jakllsch     the supplied cursor position
    674  1.1  jakllsch 
    675  1.1  jakllsch Arguments:
    676  1.1  jakllsch 
    677  1.1  jakllsch     Column, Row - The cursor position to print the string at
    678  1.1  jakllsch 
    679  1.1  jakllsch     fmt         - Format string
    680  1.1  jakllsch 
    681  1.1  jakllsch Returns:
    682  1.1  jakllsch 
    683  1.1  jakllsch     Length of string printed to the console
    684  1.1  jakllsch 
    685  1.1  jakllsch --*/
    686  1.1  jakllsch {
    687  1.1  jakllsch     va_list     args;
    688  1.1  jakllsch     UINTN       back;
    689  1.1  jakllsch 
    690  1.1  jakllsch     va_start (args, fmt);
    691  1.1  jakllsch     back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
    692  1.1  jakllsch     va_end (args);
    693  1.1  jakllsch     return back;
    694  1.1  jakllsch }
    695  1.1  jakllsch 
    696  1.1  jakllsch 
    697  1.1  jakllsch UINTN
    698  1.1  jakllsch IPrint (
    699  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE    *Out,
    700  1.2  jmcneill     IN CONST CHAR16                    *fmt,
    701  1.1  jakllsch     ...
    702  1.1  jakllsch     )
    703  1.1  jakllsch /*++
    704  1.1  jakllsch 
    705  1.1  jakllsch Routine Description:
    706  1.1  jakllsch 
    707  1.1  jakllsch     Prints a formatted unicode string to the specified console
    708  1.1  jakllsch 
    709  1.1  jakllsch Arguments:
    710  1.1  jakllsch 
    711  1.1  jakllsch     Out         - The console to print the string too
    712  1.1  jakllsch 
    713  1.1  jakllsch     fmt         - Format string
    714  1.1  jakllsch 
    715  1.1  jakllsch Returns:
    716  1.1  jakllsch 
    717  1.1  jakllsch     Length of string printed to the console
    718  1.1  jakllsch 
    719  1.1  jakllsch --*/
    720  1.1  jakllsch {
    721  1.1  jakllsch     va_list     args;
    722  1.1  jakllsch     UINTN       back;
    723  1.1  jakllsch 
    724  1.1  jakllsch     va_start (args, fmt);
    725  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
    726  1.1  jakllsch     va_end (args);
    727  1.1  jakllsch     return back;
    728  1.1  jakllsch }
    729  1.1  jakllsch 
    730  1.1  jakllsch 
    731  1.1  jakllsch UINTN
    732  1.1  jakllsch IPrintAt (
    733  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE     *Out,
    734  1.1  jakllsch     IN UINTN                            Column,
    735  1.1  jakllsch     IN UINTN                            Row,
    736  1.2  jmcneill     IN CONST CHAR16                     *fmt,
    737  1.1  jakllsch     ...
    738  1.1  jakllsch     )
    739  1.1  jakllsch /*++
    740  1.1  jakllsch 
    741  1.1  jakllsch Routine Description:
    742  1.1  jakllsch 
    743  1.1  jakllsch     Prints a formatted unicode string to the specified console, at
    744  1.1  jakllsch     the supplied cursor position
    745  1.1  jakllsch 
    746  1.1  jakllsch Arguments:
    747  1.1  jakllsch 
    748  1.2  jmcneill     Out         - The console to print the string to
    749  1.1  jakllsch 
    750  1.1  jakllsch     Column, Row - The cursor position to print the string at
    751  1.1  jakllsch 
    752  1.1  jakllsch     fmt         - Format string
    753  1.1  jakllsch 
    754  1.1  jakllsch Returns:
    755  1.1  jakllsch 
    756  1.1  jakllsch     Length of string printed to the console
    757  1.1  jakllsch 
    758  1.1  jakllsch --*/
    759  1.1  jakllsch {
    760  1.1  jakllsch     va_list     args;
    761  1.1  jakllsch     UINTN       back;
    762  1.1  jakllsch 
    763  1.1  jakllsch     va_start (args, fmt);
    764  1.2  jmcneill     back = _IPrint (Column, Row, Out, fmt, NULL, args);
    765  1.1  jakllsch     va_end (args);
    766  1.1  jakllsch     return back;
    767  1.1  jakllsch }
    768  1.1  jakllsch 
    769  1.1  jakllsch 
    770  1.1  jakllsch UINTN
    771  1.1  jakllsch _IPrint (
    772  1.1  jakllsch     IN UINTN                            Column,
    773  1.1  jakllsch     IN UINTN                            Row,
    774  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE     *Out,
    775  1.2  jmcneill     IN CONST CHAR16                     *fmt,
    776  1.2  jmcneill     IN CONST CHAR8                      *fmta,
    777  1.1  jakllsch     IN va_list                          args
    778  1.1  jakllsch     )
    779  1.1  jakllsch // Display string worker for: Print, PrintAt, IPrint, IPrintAt
    780  1.1  jakllsch {
    781  1.1  jakllsch     PRINT_STATE     ps;
    782  1.1  jakllsch     UINTN            back;
    783  1.1  jakllsch 
    784  1.1  jakllsch     ZeroMem (&ps, sizeof(ps));
    785  1.1  jakllsch     ps.Context = Out;
    786  1.2  jmcneill     ps.Output  = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString;
    787  1.2  jmcneill     ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN))  Out->SetAttribute;
    788  1.1  jakllsch     ps.Attr = Out->Mode->Attribute;
    789  1.2  jmcneill 
    790  1.1  jakllsch     back = (ps.Attr >> 4) & 0xF;
    791  1.1  jakllsch     ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
    792  1.1  jakllsch     ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
    793  1.1  jakllsch     ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
    794  1.1  jakllsch 
    795  1.1  jakllsch     if (fmt) {
    796  1.1  jakllsch         ps.fmt.pw = fmt;
    797  1.1  jakllsch     } else {
    798  1.1  jakllsch         ps.fmt.Ascii = TRUE;
    799  1.1  jakllsch         ps.fmt.pc = fmta;
    800  1.1  jakllsch     }
    801  1.1  jakllsch 
    802  1.1  jakllsch     va_copy(ps.args, args);
    803  1.1  jakllsch 
    804  1.1  jakllsch     if (Column != (UINTN) -1) {
    805  1.1  jakllsch         uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
    806  1.1  jakllsch     }
    807  1.1  jakllsch 
    808  1.1  jakllsch     back = _Print (&ps);
    809  1.1  jakllsch     va_end(ps.args);
    810  1.1  jakllsch     return back;
    811  1.1  jakllsch }
    812  1.1  jakllsch 
    813  1.1  jakllsch 
    814  1.1  jakllsch UINTN
    815  1.5  jmcneill AsciiPrint (
    816  1.2  jmcneill     IN CONST CHAR8    *fmt,
    817  1.1  jakllsch     ...
    818  1.1  jakllsch     )
    819  1.1  jakllsch /*++
    820  1.1  jakllsch 
    821  1.1  jakllsch Routine Description:
    822  1.1  jakllsch 
    823  1.1  jakllsch     For those whom really can't deal with unicode, a print
    824  1.1  jakllsch     function that takes an ascii format string
    825  1.1  jakllsch 
    826  1.1  jakllsch Arguments:
    827  1.1  jakllsch 
    828  1.1  jakllsch     fmt         - ascii format string
    829  1.1  jakllsch 
    830  1.1  jakllsch Returns:
    831  1.1  jakllsch 
    832  1.1  jakllsch     Length of string printed to the console
    833  1.1  jakllsch 
    834  1.1  jakllsch --*/
    835  1.1  jakllsch 
    836  1.1  jakllsch {
    837  1.1  jakllsch     va_list     args;
    838  1.1  jakllsch     UINTN       back;
    839  1.1  jakllsch 
    840  1.1  jakllsch     va_start (args, fmt);
    841  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
    842  1.1  jakllsch     va_end (args);
    843  1.1  jakllsch     return back;
    844  1.1  jakllsch }
    845  1.1  jakllsch 
    846  1.1  jakllsch 
    847  1.5  jmcneill UINTN
    848  1.5  jmcneill AsciiVSPrint (
    849  1.5  jmcneill     OUT CHAR8         *Str,
    850  1.5  jmcneill     IN UINTN          StrSize,
    851  1.5  jmcneill     IN CONST CHAR8    *fmt,
    852  1.5  jmcneill     va_list           args
    853  1.5  jmcneill )
    854  1.5  jmcneill /*++
    855  1.5  jmcneill 
    856  1.5  jmcneill Routine Description:
    857  1.5  jmcneill 
    858  1.5  jmcneill     Prints a formatted ascii string to a buffer using a va_list
    859  1.5  jmcneill 
    860  1.5  jmcneill Arguments:
    861  1.5  jmcneill 
    862  1.5  jmcneill     Str         - Output buffer to print the formatted string into
    863  1.5  jmcneill 
    864  1.5  jmcneill     StrSize     - Size of Str.  String is truncated to this size.
    865  1.5  jmcneill                   A size of 0 means there is no limit
    866  1.5  jmcneill 
    867  1.5  jmcneill     fmt         - The format string
    868  1.5  jmcneill 
    869  1.5  jmcneill     args        - va_list
    870  1.5  jmcneill 
    871  1.5  jmcneill 
    872  1.5  jmcneill Returns:
    873  1.5  jmcneill 
    874  1.5  jmcneill     String length returned in buffer
    875  1.5  jmcneill 
    876  1.5  jmcneill --*/
    877  1.5  jmcneill // Use UnicodeVSPrint() and convert back to ASCII
    878  1.5  jmcneill {
    879  1.5  jmcneill     CHAR16 *UnicodeStr, *UnicodeFmt;
    880  1.5  jmcneill     UINTN i, Len;
    881  1.5  jmcneill 
    882  1.5  jmcneill     UnicodeStr = AllocatePool(StrSize * sizeof(CHAR16));
    883  1.5  jmcneill     if (!UnicodeStr)
    884  1.5  jmcneill         return 0;
    885  1.5  jmcneill 
    886  1.5  jmcneill     UnicodeFmt = PoolPrint(L"%a", fmt);
    887  1.5  jmcneill     if (!UnicodeFmt) {
    888  1.5  jmcneill         FreePool(UnicodeStr);
    889  1.5  jmcneill         return 0;
    890  1.5  jmcneill     }
    891  1.5  jmcneill 
    892  1.5  jmcneill     Len = UnicodeVSPrint(UnicodeStr, StrSize, UnicodeFmt, args);
    893  1.5  jmcneill     FreePool(UnicodeFmt);
    894  1.5  jmcneill 
    895  1.5  jmcneill     // The strings are ASCII so just do a plain Unicode conversion
    896  1.5  jmcneill     for (i = 0; i < Len; i++)
    897  1.5  jmcneill         Str[i] = (CHAR8)UnicodeStr[i];
    898  1.5  jmcneill     Str[Len] = 0;
    899  1.5  jmcneill     FreePool(UnicodeStr);
    900  1.5  jmcneill 
    901  1.5  jmcneill     return Len;
    902  1.5  jmcneill }
    903  1.5  jmcneill 
    904  1.5  jmcneill 
    905  1.1  jakllsch STATIC
    906  1.1  jakllsch VOID
    907  1.1  jakllsch PFLUSH (
    908  1.1  jakllsch     IN OUT PRINT_STATE     *ps
    909  1.1  jakllsch     )
    910  1.1  jakllsch {
    911  1.1  jakllsch     *ps->Pos = 0;
    912  1.1  jakllsch     if (IsLocalPrint(ps->Output))
    913  1.2  jmcneill 	ps->Output(ps->Context, ps->Buffer);
    914  1.1  jakllsch     else
    915  1.1  jakllsch     	uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer);
    916  1.1  jakllsch     ps->Pos = ps->Buffer;
    917  1.1  jakllsch }
    918  1.1  jakllsch 
    919  1.1  jakllsch STATIC
    920  1.1  jakllsch VOID
    921  1.1  jakllsch PSETATTR (
    922  1.1  jakllsch     IN OUT PRINT_STATE  *ps,
    923  1.1  jakllsch     IN UINTN             Attr
    924  1.1  jakllsch     )
    925  1.1  jakllsch {
    926  1.1  jakllsch    PFLUSH (ps);
    927  1.1  jakllsch 
    928  1.1  jakllsch    ps->RestoreAttr = ps->Attr;
    929  1.1  jakllsch    if (ps->SetAttr) {
    930  1.1  jakllsch 	uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr);
    931  1.1  jakllsch    }
    932  1.1  jakllsch 
    933  1.1  jakllsch    ps->Attr = Attr;
    934  1.2  jmcneill }
    935  1.1  jakllsch 
    936  1.1  jakllsch STATIC
    937  1.1  jakllsch VOID
    938  1.1  jakllsch PPUTC (
    939  1.1  jakllsch     IN OUT PRINT_STATE     *ps,
    940  1.1  jakllsch     IN CHAR16              c
    941  1.1  jakllsch     )
    942  1.1  jakllsch {
    943  1.1  jakllsch     // if this is a newline, add a carraige return
    944  1.1  jakllsch     if (c == '\n') {
    945  1.1  jakllsch         PPUTC (ps, '\r');
    946  1.1  jakllsch     }
    947  1.1  jakllsch 
    948  1.1  jakllsch     *ps->Pos = c;
    949  1.1  jakllsch     ps->Pos += 1;
    950  1.1  jakllsch     ps->Len += 1;
    951  1.1  jakllsch 
    952  1.1  jakllsch     // if at the end of the buffer, flush it
    953  1.1  jakllsch     if (ps->Pos >= ps->End) {
    954  1.1  jakllsch         PFLUSH(ps);
    955  1.1  jakllsch     }
    956  1.1  jakllsch }
    957  1.1  jakllsch 
    958  1.1  jakllsch 
    959  1.1  jakllsch STATIC
    960  1.1  jakllsch CHAR16
    961  1.1  jakllsch PGETC (
    962  1.1  jakllsch     IN POINTER      *p
    963  1.1  jakllsch     )
    964  1.1  jakllsch {
    965  1.1  jakllsch     CHAR16      c;
    966  1.1  jakllsch 
    967  1.1  jakllsch     c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
    968  1.1  jakllsch     p->Index += 1;
    969  1.1  jakllsch 
    970  1.1  jakllsch     return  c;
    971  1.1  jakllsch }
    972  1.1  jakllsch 
    973  1.1  jakllsch 
    974  1.1  jakllsch STATIC
    975  1.1  jakllsch VOID
    976  1.1  jakllsch PITEM (
    977  1.1  jakllsch     IN OUT PRINT_STATE  *ps
    978  1.1  jakllsch     )
    979  1.1  jakllsch {
    980  1.1  jakllsch     UINTN               Len, i;
    981  1.1  jakllsch     PRINT_ITEM          *Item;
    982  1.1  jakllsch     CHAR16              c;
    983  1.1  jakllsch 
    984  1.1  jakllsch     // Get the length of the item
    985  1.1  jakllsch     Item = ps->Item;
    986  1.1  jakllsch     Item->Item.Index = 0;
    987  1.1  jakllsch     while (Item->Item.Index < Item->FieldWidth) {
    988  1.1  jakllsch         c = PGETC(&Item->Item);
    989  1.1  jakllsch         if (!c) {
    990  1.1  jakllsch             Item->Item.Index -= 1;
    991  1.1  jakllsch             break;
    992  1.1  jakllsch         }
    993  1.1  jakllsch     }
    994  1.1  jakllsch     Len = Item->Item.Index;
    995  1.1  jakllsch 
    996  1.1  jakllsch     // if there is no item field width, use the items width
    997  1.1  jakllsch     if (Item->FieldWidth == (UINTN) -1) {
    998  1.1  jakllsch         Item->FieldWidth = Len;
    999  1.1  jakllsch     }
   1000  1.1  jakllsch 
   1001  1.1  jakllsch     // if item is larger then width, update width
   1002  1.1  jakllsch     if (Len > Item->Width) {
   1003  1.1  jakllsch         Item->Width = Len;
   1004  1.1  jakllsch     }
   1005  1.1  jakllsch 
   1006  1.1  jakllsch 
   1007  1.1  jakllsch     // if pad field before, add pad char
   1008  1.1  jakllsch     if (Item->PadBefore) {
   1009  1.1  jakllsch         for (i=Item->Width; i < Item->FieldWidth; i+=1) {
   1010  1.1  jakllsch             PPUTC (ps, ' ');
   1011  1.1  jakllsch         }
   1012  1.1  jakllsch     }
   1013  1.1  jakllsch 
   1014  1.1  jakllsch     // pad item
   1015  1.1  jakllsch     for (i=Len; i < Item->Width; i++) {
   1016  1.1  jakllsch         PPUTC (ps, Item->Pad);
   1017  1.1  jakllsch     }
   1018  1.1  jakllsch 
   1019  1.1  jakllsch     // add the item
   1020  1.2  jmcneill     Item->Item.Index=0;
   1021  1.1  jakllsch     while (Item->Item.Index < Len) {
   1022  1.1  jakllsch         PPUTC (ps, PGETC(&Item->Item));
   1023  1.1  jakllsch     }
   1024  1.1  jakllsch 
   1025  1.1  jakllsch     // If pad at the end, add pad char
   1026  1.1  jakllsch     if (!Item->PadBefore) {
   1027  1.1  jakllsch         for (i=Item->Width; i < Item->FieldWidth; i+=1) {
   1028  1.1  jakllsch             PPUTC (ps, ' ');
   1029  1.1  jakllsch         }
   1030  1.1  jakllsch     }
   1031  1.1  jakllsch }
   1032  1.1  jakllsch 
   1033  1.1  jakllsch 
   1034  1.1  jakllsch STATIC
   1035  1.1  jakllsch UINTN
   1036  1.1  jakllsch _Print (
   1037  1.1  jakllsch     IN PRINT_STATE     *ps
   1038  1.1  jakllsch     )
   1039  1.1  jakllsch /*++
   1040  1.1  jakllsch 
   1041  1.1  jakllsch Routine Description:
   1042  1.1  jakllsch 
   1043  1.1  jakllsch     %w.lF   -   w = width
   1044  1.1  jakllsch                 l = field width
   1045  1.1  jakllsch                 F = format of arg
   1046  1.1  jakllsch 
   1047  1.1  jakllsch   Args F:
   1048  1.1  jakllsch     0       -   pad with zeros
   1049  1.1  jakllsch     -       -   justify on left (default is on right)
   1050  1.2  jmcneill     ,       -   add comma's to field
   1051  1.1  jakllsch     *       -   width provided on stack
   1052  1.1  jakllsch     n       -   Set output attribute to normal (for this field only)
   1053  1.1  jakllsch     h       -   Set output attribute to highlight (for this field only)
   1054  1.1  jakllsch     e       -   Set output attribute to error (for this field only)
   1055  1.1  jakllsch     l       -   Value is 64 bits
   1056  1.1  jakllsch 
   1057  1.1  jakllsch     a       -   ascii string
   1058  1.1  jakllsch     s       -   unicode string
   1059  1.1  jakllsch     X       -   fixed 8 byte value in hex
   1060  1.1  jakllsch     x       -   hex value
   1061  1.2  jmcneill     d       -   value as signed decimal
   1062  1.2  jmcneill     u       -   value as unsigned decimal
   1063  1.2  jmcneill     f       -   value as floating point
   1064  1.1  jakllsch     c       -   Unicode char
   1065  1.1  jakllsch     t       -   EFI time structure
   1066  1.1  jakllsch     g       -   Pointer to GUID
   1067  1.1  jakllsch     r       -   EFI status code (result code)
   1068  1.2  jmcneill     D       -   pointer to Device Path with normal ending.
   1069  1.1  jakllsch 
   1070  1.1  jakllsch     N       -   Set output attribute to normal
   1071  1.1  jakllsch     H       -   Set output attribute to highlight
   1072  1.1  jakllsch     E       -   Set output attribute to error
   1073  1.1  jakllsch     %       -   Print a %
   1074  1.2  jmcneill 
   1075  1.1  jakllsch Arguments:
   1076  1.1  jakllsch 
   1077  1.1  jakllsch     SystemTable     - The system table
   1078  1.1  jakllsch 
   1079  1.1  jakllsch Returns:
   1080  1.1  jakllsch 
   1081  1.2  jmcneill     Number of charactors written
   1082  1.1  jakllsch 
   1083  1.1  jakllsch --*/
   1084  1.1  jakllsch {
   1085  1.1  jakllsch     CHAR16          c;
   1086  1.1  jakllsch     UINTN           Attr;
   1087  1.1  jakllsch     PRINT_ITEM      Item;
   1088  1.1  jakllsch     CHAR16          Buffer[PRINT_STRING_LEN];
   1089  1.1  jakllsch 
   1090  1.1  jakllsch     ps->Len = 0;
   1091  1.1  jakllsch     ps->Buffer = Buffer;
   1092  1.1  jakllsch     ps->Pos = Buffer;
   1093  1.1  jakllsch     ps->End = Buffer + PRINT_STRING_LEN - 1;
   1094  1.1  jakllsch     ps->Item = &Item;
   1095  1.1  jakllsch 
   1096  1.1  jakllsch     ps->fmt.Index = 0;
   1097  1.1  jakllsch     while ((c = PGETC(&ps->fmt))) {
   1098  1.1  jakllsch 
   1099  1.1  jakllsch         if (c != '%') {
   1100  1.1  jakllsch             PPUTC ( ps, c );
   1101  1.2  jmcneill             continue;
   1102  1.1  jakllsch         }
   1103  1.1  jakllsch 
   1104  1.1  jakllsch         // setup for new item
   1105  1.1  jakllsch         Item.FieldWidth = (UINTN) -1;
   1106  1.1  jakllsch         Item.Width = 0;
   1107  1.1  jakllsch         Item.WidthParse = &Item.Width;
   1108  1.1  jakllsch         Item.Pad = ' ';
   1109  1.1  jakllsch         Item.PadBefore = TRUE;
   1110  1.1  jakllsch         Item.Comma = FALSE;
   1111  1.1  jakllsch         Item.Long = FALSE;
   1112  1.1  jakllsch         Item.Item.Ascii = FALSE;
   1113  1.1  jakllsch         Item.Item.pw = NULL;
   1114  1.1  jakllsch         ps->RestoreAttr = 0;
   1115  1.1  jakllsch         Attr = 0;
   1116  1.1  jakllsch 
   1117  1.1  jakllsch         while ((c = PGETC(&ps->fmt))) {
   1118  1.1  jakllsch 
   1119  1.1  jakllsch             switch (c) {
   1120  1.2  jmcneill 
   1121  1.1  jakllsch             case '%':
   1122  1.1  jakllsch                 //
   1123  1.1  jakllsch                 // %% -> %
   1124  1.1  jakllsch                 //
   1125  1.2  jmcneill                 Item.Scratch[0] = '%';
   1126  1.2  jmcneill                 Item.Scratch[1] = 0;
   1127  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1128  1.1  jakllsch                 break;
   1129  1.1  jakllsch 
   1130  1.1  jakllsch             case '0':
   1131  1.1  jakllsch                 Item.Pad = '0';
   1132  1.1  jakllsch                 break;
   1133  1.1  jakllsch 
   1134  1.1  jakllsch             case '-':
   1135  1.1  jakllsch                 Item.PadBefore = FALSE;
   1136  1.1  jakllsch                 break;
   1137  1.1  jakllsch 
   1138  1.1  jakllsch             case ',':
   1139  1.1  jakllsch                 Item.Comma = TRUE;
   1140  1.1  jakllsch                 break;
   1141  1.1  jakllsch 
   1142  1.1  jakllsch             case '.':
   1143  1.1  jakllsch                 Item.WidthParse = &Item.FieldWidth;
   1144  1.1  jakllsch                 break;
   1145  1.1  jakllsch 
   1146  1.1  jakllsch             case '*':
   1147  1.1  jakllsch                 *Item.WidthParse = va_arg(ps->args, UINTN);
   1148  1.1  jakllsch                 break;
   1149  1.2  jmcneill 
   1150  1.1  jakllsch             case '1':
   1151  1.1  jakllsch             case '2':
   1152  1.1  jakllsch             case '3':
   1153  1.1  jakllsch             case '4':
   1154  1.1  jakllsch             case '5':
   1155  1.1  jakllsch             case '6':
   1156  1.1  jakllsch             case '7':
   1157  1.1  jakllsch             case '8':
   1158  1.1  jakllsch             case '9':
   1159  1.1  jakllsch                 *Item.WidthParse = 0;
   1160  1.1  jakllsch                 do {
   1161  1.1  jakllsch                     *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
   1162  1.1  jakllsch                     c = PGETC(&ps->fmt);
   1163  1.1  jakllsch                 } while (c >= '0'  &&  c <= '9') ;
   1164  1.1  jakllsch                 ps->fmt.Index -= 1;
   1165  1.1  jakllsch                 break;
   1166  1.1  jakllsch 
   1167  1.1  jakllsch             case 'a':
   1168  1.1  jakllsch                 Item.Item.pc = va_arg(ps->args, CHAR8 *);
   1169  1.1  jakllsch                 Item.Item.Ascii = TRUE;
   1170  1.1  jakllsch                 if (!Item.Item.pc) {
   1171  1.1  jakllsch                     Item.Item.pc = (CHAR8 *)"(null)";
   1172  1.1  jakllsch                 }
   1173  1.1  jakllsch                 break;
   1174  1.1  jakllsch 
   1175  1.1  jakllsch             case 's':
   1176  1.1  jakllsch                 Item.Item.pw = va_arg(ps->args, CHAR16 *);
   1177  1.1  jakllsch                 if (!Item.Item.pw) {
   1178  1.1  jakllsch                     Item.Item.pw = L"(null)";
   1179  1.1  jakllsch                 }
   1180  1.1  jakllsch                 break;
   1181  1.1  jakllsch 
   1182  1.1  jakllsch             case 'c':
   1183  1.2  jmcneill                 Item.Scratch[0] = (CHAR16) va_arg(ps->args, UINTN);
   1184  1.2  jmcneill                 Item.Scratch[1] = 0;
   1185  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1186  1.1  jakllsch                 break;
   1187  1.1  jakllsch 
   1188  1.1  jakllsch             case 'l':
   1189  1.1  jakllsch                 Item.Long = TRUE;
   1190  1.1  jakllsch                 break;
   1191  1.1  jakllsch 
   1192  1.1  jakllsch             case 'X':
   1193  1.1  jakllsch                 Item.Width = Item.Long ? 16 : 8;
   1194  1.1  jakllsch                 Item.Pad = '0';
   1195  1.2  jmcneill #if __GNUC__ >= 7
   1196  1.2  jmcneill 		__attribute__ ((fallthrough));
   1197  1.2  jmcneill #endif
   1198  1.1  jakllsch             case 'x':
   1199  1.1  jakllsch                 ValueToHex (
   1200  1.2  jmcneill                     Item.Scratch,
   1201  1.1  jakllsch                     Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
   1202  1.1  jakllsch                     );
   1203  1.2  jmcneill                 Item.Item.pw = Item.Scratch;
   1204  1.1  jakllsch 
   1205  1.1  jakllsch                 break;
   1206  1.2  jmcneill 
   1207  1.1  jakllsch 
   1208  1.1  jakllsch             case 'g':
   1209  1.2  jmcneill                 GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *));
   1210  1.2  jmcneill                 Item.Item.pw = Item.Scratch;
   1211  1.2  jmcneill                 break;
   1212  1.2  jmcneill 
   1213  1.2  jmcneill             case 'u':
   1214  1.2  jmcneill                 ValueToString (
   1215  1.2  jmcneill                     Item.Scratch,
   1216  1.2  jmcneill                     Item.Comma,
   1217  1.2  jmcneill                     Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
   1218  1.2  jmcneill                     );
   1219  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1220  1.1  jakllsch                 break;
   1221  1.1  jakllsch 
   1222  1.1  jakllsch             case 'd':
   1223  1.2  jmcneill                 ValueToString (
   1224  1.2  jmcneill                     Item.Scratch,
   1225  1.2  jmcneill                     Item.Comma,
   1226  1.2  jmcneill                     Item.Long ? va_arg(ps->args, INT64) : va_arg(ps->args, INT32)
   1227  1.2  jmcneill                     );
   1228  1.2  jmcneill                 Item.Item.pw = Item.Scratch;
   1229  1.2  jmcneill                 break;
   1230  1.2  jmcneill 
   1231  1.2  jmcneill             case 'D':
   1232  1.2  jmcneill             {
   1233  1.2  jmcneill                 EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *);
   1234  1.2  jmcneill                 CHAR16 *dpstr = DevicePathToStr(dp);
   1235  1.2  jmcneill                 StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN);
   1236  1.2  jmcneill                 Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0';
   1237  1.2  jmcneill                 FreePool(dpstr);
   1238  1.2  jmcneill 
   1239  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1240  1.2  jmcneill                 break;
   1241  1.2  jmcneill             }
   1242  1.2  jmcneill 
   1243  1.2  jmcneill #ifndef __NetBSD__
   1244  1.2  jmcneill             case 'f':
   1245  1.2  jmcneill                 FloatToString (
   1246  1.2  jmcneill                     Item.Scratch,
   1247  1.2  jmcneill                     Item.Comma,
   1248  1.2  jmcneill                     va_arg(ps->args, double)
   1249  1.1  jakllsch                     );
   1250  1.2  jmcneill                 Item.Item.pw = Item.Scratch;
   1251  1.2  jmcneill                 break;
   1252  1.2  jmcneill #endif
   1253  1.2  jmcneill 
   1254  1.1  jakllsch             case 't':
   1255  1.2  jmcneill                 TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *));
   1256  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1257  1.1  jakllsch                 break;
   1258  1.1  jakllsch 
   1259  1.1  jakllsch             case 'r':
   1260  1.2  jmcneill                 StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS));
   1261  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1262  1.1  jakllsch                 break;
   1263  1.1  jakllsch 
   1264  1.1  jakllsch             case 'n':
   1265  1.1  jakllsch                 PSETATTR(ps, ps->AttrNorm);
   1266  1.1  jakllsch                 break;
   1267  1.1  jakllsch 
   1268  1.1  jakllsch             case 'h':
   1269  1.1  jakllsch                 PSETATTR(ps, ps->AttrHighlight);
   1270  1.1  jakllsch                 break;
   1271  1.1  jakllsch 
   1272  1.1  jakllsch             case 'e':
   1273  1.1  jakllsch                 PSETATTR(ps, ps->AttrError);
   1274  1.1  jakllsch                 break;
   1275  1.1  jakllsch 
   1276  1.1  jakllsch             case 'N':
   1277  1.1  jakllsch                 Attr = ps->AttrNorm;
   1278  1.1  jakllsch                 break;
   1279  1.1  jakllsch 
   1280  1.1  jakllsch             case 'H':
   1281  1.1  jakllsch                 Attr = ps->AttrHighlight;
   1282  1.1  jakllsch                 break;
   1283  1.1  jakllsch 
   1284  1.1  jakllsch             case 'E':
   1285  1.1  jakllsch                 Attr = ps->AttrError;
   1286  1.1  jakllsch                 break;
   1287  1.1  jakllsch 
   1288  1.1  jakllsch             default:
   1289  1.2  jmcneill                 Item.Scratch[0] = '?';
   1290  1.2  jmcneill                 Item.Scratch[1] = 0;
   1291  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1292  1.1  jakllsch                 break;
   1293  1.1  jakllsch             }
   1294  1.1  jakllsch 
   1295  1.1  jakllsch             // if we have an Item
   1296  1.1  jakllsch             if (Item.Item.pw) {
   1297  1.1  jakllsch                 PITEM (ps);
   1298  1.1  jakllsch                 break;
   1299  1.1  jakllsch             }
   1300  1.1  jakllsch 
   1301  1.1  jakllsch             // if we have an Attr set
   1302  1.1  jakllsch             if (Attr) {
   1303  1.1  jakllsch                 PSETATTR(ps, Attr);
   1304  1.1  jakllsch                 ps->RestoreAttr = 0;
   1305  1.1  jakllsch                 break;
   1306  1.1  jakllsch             }
   1307  1.1  jakllsch         }
   1308  1.1  jakllsch 
   1309  1.1  jakllsch         if (ps->RestoreAttr) {
   1310  1.1  jakllsch             PSETATTR(ps, ps->RestoreAttr);
   1311  1.1  jakllsch         }
   1312  1.1  jakllsch     }
   1313  1.1  jakllsch 
   1314  1.1  jakllsch     // Flush buffer
   1315  1.1  jakllsch     PFLUSH (ps);
   1316  1.1  jakllsch     return ps->Len;
   1317  1.1  jakllsch }
   1318  1.1  jakllsch 
   1319  1.1  jakllsch STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
   1320  1.1  jakllsch                       '8','9','A','B','C','D','E','F'};
   1321  1.1  jakllsch 
   1322  1.1  jakllsch VOID
   1323  1.1  jakllsch ValueToHex (
   1324  1.1  jakllsch     IN CHAR16   *Buffer,
   1325  1.1  jakllsch     IN UINT64   v
   1326  1.1  jakllsch     )
   1327  1.1  jakllsch {
   1328  1.1  jakllsch     CHAR8           str[30], *p1;
   1329  1.1  jakllsch     CHAR16          *p2;
   1330  1.1  jakllsch 
   1331  1.1  jakllsch     if (!v) {
   1332  1.1  jakllsch         Buffer[0] = '0';
   1333  1.1  jakllsch         Buffer[1] = 0;
   1334  1.1  jakllsch         return ;
   1335  1.1  jakllsch     }
   1336  1.1  jakllsch 
   1337  1.1  jakllsch     p1 = str;
   1338  1.1  jakllsch     p2 = Buffer;
   1339  1.1  jakllsch 
   1340  1.1  jakllsch     while (v) {
   1341  1.2  jmcneill         // Without the cast, the MSVC compiler may insert a reference to __allmull
   1342  1.2  jmcneill         *(p1++) = Hex[(UINTN)(v & 0xf)];
   1343  1.1  jakllsch         v = RShiftU64 (v, 4);
   1344  1.1  jakllsch     }
   1345  1.1  jakllsch 
   1346  1.1  jakllsch     while (p1 != str) {
   1347  1.1  jakllsch         *(p2++) = *(--p1);
   1348  1.1  jakllsch     }
   1349  1.1  jakllsch     *p2 = 0;
   1350  1.1  jakllsch }
   1351  1.1  jakllsch 
   1352  1.1  jakllsch 
   1353  1.1  jakllsch VOID
   1354  1.1  jakllsch ValueToString (
   1355  1.1  jakllsch     IN CHAR16   *Buffer,
   1356  1.1  jakllsch     IN BOOLEAN  Comma,
   1357  1.1  jakllsch     IN INT64    v
   1358  1.1  jakllsch     )
   1359  1.1  jakllsch {
   1360  1.1  jakllsch     STATIC CHAR8 ca[] = {  3, 1, 2 };
   1361  1.1  jakllsch     CHAR8        str[40], *p1;
   1362  1.1  jakllsch     CHAR16       *p2;
   1363  1.1  jakllsch     UINTN        c, r;
   1364  1.1  jakllsch 
   1365  1.1  jakllsch     if (!v) {
   1366  1.1  jakllsch         Buffer[0] = '0';
   1367  1.1  jakllsch         Buffer[1] = 0;
   1368  1.1  jakllsch         return ;
   1369  1.1  jakllsch     }
   1370  1.1  jakllsch 
   1371  1.1  jakllsch     p1 = str;
   1372  1.1  jakllsch     p2 = Buffer;
   1373  1.1  jakllsch 
   1374  1.1  jakllsch     if (v < 0) {
   1375  1.1  jakllsch         *(p2++) = '-';
   1376  1.1  jakllsch         v = -v;
   1377  1.1  jakllsch     }
   1378  1.1  jakllsch 
   1379  1.1  jakllsch     while (v) {
   1380  1.1  jakllsch         v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
   1381  1.1  jakllsch         *(p1++) = (CHAR8)r + '0';
   1382  1.1  jakllsch     }
   1383  1.1  jakllsch 
   1384  1.5  jmcneill     c = (UINTN) (Comma ? ca[(p1 - str) % 3] : 999) + 1;
   1385  1.1  jakllsch     while (p1 != str) {
   1386  1.1  jakllsch 
   1387  1.1  jakllsch         c -= 1;
   1388  1.1  jakllsch         if (!c) {
   1389  1.1  jakllsch             *(p2++) = ',';
   1390  1.1  jakllsch             c = 3;
   1391  1.1  jakllsch         }
   1392  1.1  jakllsch 
   1393  1.1  jakllsch         *(p2++) = *(--p1);
   1394  1.1  jakllsch     }
   1395  1.1  jakllsch     *p2 = 0;
   1396  1.1  jakllsch }
   1397  1.1  jakllsch 
   1398  1.2  jmcneill #ifndef __NetBSD__
   1399  1.2  jmcneill VOID
   1400  1.2  jmcneill FloatToString (
   1401  1.2  jmcneill     IN CHAR16   *Buffer,
   1402  1.2  jmcneill     IN BOOLEAN  Comma,
   1403  1.2  jmcneill     IN double   v
   1404  1.2  jmcneill     )
   1405  1.2  jmcneill {
   1406  1.2  jmcneill     /*
   1407  1.2  jmcneill      * Integer part.
   1408  1.2  jmcneill      */
   1409  1.2  jmcneill     INTN i = (INTN)v;
   1410  1.2  jmcneill     ValueToString(Buffer, Comma, i);
   1411  1.2  jmcneill 
   1412  1.2  jmcneill 
   1413  1.2  jmcneill     /*
   1414  1.2  jmcneill      * Decimal point.
   1415  1.2  jmcneill      */
   1416  1.2  jmcneill     UINTN x = StrLen(Buffer);
   1417  1.2  jmcneill     Buffer[x] = L'.';
   1418  1.2  jmcneill     x++;
   1419  1.2  jmcneill 
   1420  1.2  jmcneill 
   1421  1.2  jmcneill     /*
   1422  1.2  jmcneill      * Keep fractional part.
   1423  1.2  jmcneill      */
   1424  1.2  jmcneill     float f = (float)(v - i);
   1425  1.2  jmcneill     if (f < 0) f = -f;
   1426  1.2  jmcneill 
   1427  1.2  jmcneill 
   1428  1.2  jmcneill     /*
   1429  1.2  jmcneill      * Leading fractional zeroes.
   1430  1.2  jmcneill      */
   1431  1.2  jmcneill     f *= 10.0;
   1432  1.2  jmcneill     while (   (f != 0)
   1433  1.2  jmcneill            && ((INTN)f == 0))
   1434  1.2  jmcneill     {
   1435  1.2  jmcneill       Buffer[x] = L'0';
   1436  1.2  jmcneill       x++;
   1437  1.2  jmcneill       f *= 10.0;
   1438  1.2  jmcneill     }
   1439  1.2  jmcneill 
   1440  1.2  jmcneill 
   1441  1.2  jmcneill     /*
   1442  1.2  jmcneill      * Fractional digits.
   1443  1.2  jmcneill      */
   1444  1.2  jmcneill     while ((float)(INTN)f != f)
   1445  1.2  jmcneill     {
   1446  1.2  jmcneill       f *= 10;
   1447  1.2  jmcneill     }
   1448  1.2  jmcneill     ValueToString(Buffer + x, FALSE, (INTN)f);
   1449  1.2  jmcneill     return;
   1450  1.2  jmcneill }
   1451  1.2  jmcneill #endif
   1452  1.2  jmcneill 
   1453  1.1  jakllsch VOID
   1454  1.1  jakllsch TimeToString (
   1455  1.1  jakllsch     OUT CHAR16      *Buffer,
   1456  1.1  jakllsch     IN EFI_TIME     *Time
   1457  1.1  jakllsch     )
   1458  1.1  jakllsch {
   1459  1.1  jakllsch     UINTN       Hour, Year;
   1460  1.1  jakllsch     CHAR16      AmPm;
   1461  1.1  jakllsch 
   1462  1.1  jakllsch     AmPm = 'a';
   1463  1.1  jakllsch     Hour = Time->Hour;
   1464  1.1  jakllsch     if (Time->Hour == 0) {
   1465  1.1  jakllsch         Hour = 12;
   1466  1.1  jakllsch     } else if (Time->Hour >= 12) {
   1467  1.1  jakllsch         AmPm = 'p';
   1468  1.1  jakllsch         if (Time->Hour >= 13) {
   1469  1.1  jakllsch             Hour -= 12;
   1470  1.1  jakllsch         }
   1471  1.1  jakllsch     }
   1472  1.1  jakllsch 
   1473  1.1  jakllsch     Year = Time->Year % 100;
   1474  1.2  jmcneill 
   1475  1.1  jakllsch     // bugbug: for now just print it any old way
   1476  1.5  jmcneill     UnicodeSPrint (Buffer, 0, L"%02d/%02d/%02d  %02d:%02d%c",
   1477  1.1  jakllsch         Time->Month,
   1478  1.1  jakllsch         Time->Day,
   1479  1.1  jakllsch         Year,
   1480  1.1  jakllsch         Hour,
   1481  1.1  jakllsch         Time->Minute,
   1482  1.1  jakllsch         AmPm
   1483  1.1  jakllsch         );
   1484  1.2  jmcneill }
   1485  1.1  jakllsch 
   1486  1.1  jakllsch 
   1487  1.1  jakllsch 
   1488  1.1  jakllsch 
   1489  1.1  jakllsch VOID
   1490  1.1  jakllsch DumpHex (
   1491  1.1  jakllsch     IN UINTN        Indent,
   1492  1.1  jakllsch     IN UINTN        Offset,
   1493  1.1  jakllsch     IN UINTN        DataSize,
   1494  1.1  jakllsch     IN VOID         *UserData
   1495  1.1  jakllsch     )
   1496  1.1  jakllsch {
   1497  1.1  jakllsch     CHAR8           *Data, Val[50], Str[20], c;
   1498  1.1  jakllsch     UINTN           Size, Index;
   1499  1.2  jmcneill 
   1500  1.1  jakllsch     UINTN           ScreenCount;
   1501  1.1  jakllsch     UINTN           TempColumn;
   1502  1.1  jakllsch     UINTN           ScreenSize;
   1503  1.1  jakllsch     CHAR16          ReturnStr[1];
   1504  1.1  jakllsch 
   1505  1.1  jakllsch 
   1506  1.1  jakllsch     uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
   1507  1.1  jakllsch     ScreenCount = 0;
   1508  1.1  jakllsch     ScreenSize -= 2;
   1509  1.1  jakllsch 
   1510  1.1  jakllsch     Data = UserData;
   1511  1.1  jakllsch     while (DataSize) {
   1512  1.1  jakllsch         Size = 16;
   1513  1.1  jakllsch         if (Size > DataSize) {
   1514  1.1  jakllsch             Size = DataSize;
   1515  1.1  jakllsch         }
   1516  1.1  jakllsch 
   1517  1.1  jakllsch         for (Index=0; Index < Size; Index += 1) {
   1518  1.1  jakllsch             c = Data[Index];
   1519  1.1  jakllsch             Val[Index*3+0] = Hex[c>>4];
   1520  1.1  jakllsch             Val[Index*3+1] = Hex[c&0xF];
   1521  1.1  jakllsch             Val[Index*3+2] = (Index == 7)?'-':' ';
   1522  1.1  jakllsch             Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
   1523  1.1  jakllsch         }
   1524  1.1  jakllsch 
   1525  1.1  jakllsch         Val[Index*3] = 0;
   1526  1.1  jakllsch         Str[Index] = 0;
   1527  1.1  jakllsch         Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
   1528  1.1  jakllsch 
   1529  1.1  jakllsch         Data += Size;
   1530  1.1  jakllsch         Offset += Size;
   1531  1.1  jakllsch         DataSize -= Size;
   1532  1.1  jakllsch 
   1533  1.1  jakllsch         ScreenCount++;
   1534  1.1  jakllsch         if (ScreenCount >= ScreenSize && ScreenSize != 0) {
   1535  1.1  jakllsch             //
   1536  1.1  jakllsch             // If ScreenSize == 0 we have the console redirected so don't
   1537  1.1  jakllsch             //  block updates
   1538  1.1  jakllsch             //
   1539  1.1  jakllsch             ScreenCount = 0;
   1540  1.1  jakllsch             Print (L"Press Enter to continue :");
   1541  1.1  jakllsch             Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
   1542  1.1  jakllsch             Print (L"\n");
   1543  1.1  jakllsch         }
   1544  1.1  jakllsch 
   1545  1.1  jakllsch     }
   1546  1.1  jakllsch }
   1547