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