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