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