Home | History | Annotate | Line # | Download | only in lib
print.c revision 1.1
      1  1.1  jakllsch /*	$NetBSD: print.c,v 1.1 2014/04/01 16:16:06 jakllsch 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.1  jakllsch         CHAR16          *pw;
     61  1.1  jakllsch         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.1  jakllsch     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.1  jakllsch     INTN EFIAPI       (*Output)(VOID *context, CHAR16 *str);
    101  1.1  jakllsch     INTN EFIAPI       (*SetAttr)(VOID *context, UINTN attr);
    102  1.1  jakllsch     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.1  jakllsch     IN CHAR16                           *fmt,
    125  1.1  jakllsch     IN 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.1  jakllsch     IN INTN      mask,
    187  1.1  jakllsch     IN 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.1  jakllsch                   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.1  jakllsch     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.1  jakllsch     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.1  jakllsch         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.1  jakllsch         ps.SetAttr (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.1  jakllsch         ps.SetAttr (ps.Context, SavedAttribute);
    276  1.1  jakllsch     }
    277  1.1  jakllsch 
    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.1  jakllsch         spc->str[spc->maxlen-1] = 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.1  jakllsch                         spc->str,
    384  1.1  jakllsch                         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.1  jakllsch     IN CHAR16           *fmt,
    406  1.1  jakllsch     IN va_list          args,
    407  1.1  jakllsch     IN OUT POOL_PRINT   *spc,
    408  1.1  jakllsch     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.1  jakllsch SPrint (
    427  1.1  jakllsch     OUT CHAR16  *Str,
    428  1.1  jakllsch     IN UINTN    StrSize,
    429  1.1  jakllsch     IN CHAR16   *fmt,
    430  1.1  jakllsch     ...
    431  1.1  jakllsch     )
    432  1.1  jakllsch /*++
    433  1.1  jakllsch 
    434  1.1  jakllsch Routine Description:
    435  1.1  jakllsch 
    436  1.1  jakllsch     Prints a formatted unicode string to a buffer
    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.1  jakllsch Returns:
    448  1.1  jakllsch 
    449  1.1  jakllsch     String length returned in buffer
    450  1.1  jakllsch 
    451  1.1  jakllsch --*/
    452  1.1  jakllsch {
    453  1.1  jakllsch     POOL_PRINT          spc;
    454  1.1  jakllsch     va_list             args;
    455  1.1  jakllsch 
    456  1.1  jakllsch 
    457  1.1  jakllsch     va_start (args, fmt);
    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.1  jakllsch     va_end (args);
    464  1.1  jakllsch     return spc.len;
    465  1.1  jakllsch }
    466  1.1  jakllsch 
    467  1.1  jakllsch 
    468  1.1  jakllsch CHAR16 *
    469  1.1  jakllsch PoolPrint (
    470  1.1  jakllsch     IN CHAR16           *fmt,
    471  1.1  jakllsch     ...
    472  1.1  jakllsch     )
    473  1.1  jakllsch /*++
    474  1.1  jakllsch 
    475  1.1  jakllsch Routine Description:
    476  1.1  jakllsch 
    477  1.1  jakllsch     Prints a formatted unicode string to allocated pool.  The caller
    478  1.1  jakllsch     must free the resulting buffer.
    479  1.1  jakllsch 
    480  1.1  jakllsch Arguments:
    481  1.1  jakllsch 
    482  1.1  jakllsch     fmt         - The format string
    483  1.1  jakllsch 
    484  1.1  jakllsch Returns:
    485  1.1  jakllsch 
    486  1.1  jakllsch     Allocated buffer with the formatted string printed in it.
    487  1.1  jakllsch     The caller must free the allocated buffer.   The buffer
    488  1.1  jakllsch     allocation is not packed.
    489  1.1  jakllsch 
    490  1.1  jakllsch --*/
    491  1.1  jakllsch {
    492  1.1  jakllsch     POOL_PRINT          spc;
    493  1.1  jakllsch     va_list             args;
    494  1.1  jakllsch 
    495  1.1  jakllsch     ZeroMem (&spc, sizeof(spc));
    496  1.1  jakllsch     va_start (args, fmt);
    497  1.1  jakllsch     _PoolCatPrint (fmt, args, &spc, _PoolPrint);
    498  1.1  jakllsch     va_end (args);
    499  1.1  jakllsch     return spc.str;
    500  1.1  jakllsch }
    501  1.1  jakllsch 
    502  1.1  jakllsch 
    503  1.1  jakllsch 
    504  1.1  jakllsch CHAR16 *
    505  1.1  jakllsch CatPrint (
    506  1.1  jakllsch     IN OUT POOL_PRINT   *Str,
    507  1.1  jakllsch     IN CHAR16           *fmt,
    508  1.1  jakllsch     ...
    509  1.1  jakllsch     )
    510  1.1  jakllsch /*++
    511  1.1  jakllsch 
    512  1.1  jakllsch Routine Description:
    513  1.1  jakllsch 
    514  1.1  jakllsch     Concatenates a formatted unicode string to allocated pool.
    515  1.1  jakllsch     The caller must free the resulting buffer.
    516  1.1  jakllsch 
    517  1.1  jakllsch Arguments:
    518  1.1  jakllsch 
    519  1.1  jakllsch     Str         - Tracks the allocated pool, size in use, and
    520  1.1  jakllsch                   amount of pool allocated.
    521  1.1  jakllsch 
    522  1.1  jakllsch     fmt         - The format string
    523  1.1  jakllsch 
    524  1.1  jakllsch Returns:
    525  1.1  jakllsch 
    526  1.1  jakllsch     Allocated buffer with the formatted string printed in it.
    527  1.1  jakllsch     The caller must free the allocated buffer.   The buffer
    528  1.1  jakllsch     allocation is not packed.
    529  1.1  jakllsch 
    530  1.1  jakllsch --*/
    531  1.1  jakllsch {
    532  1.1  jakllsch     va_list             args;
    533  1.1  jakllsch 
    534  1.1  jakllsch     va_start (args, fmt);
    535  1.1  jakllsch     _PoolCatPrint (fmt, args, Str, _PoolPrint);
    536  1.1  jakllsch     va_end (args);
    537  1.1  jakllsch     return Str->str;
    538  1.1  jakllsch }
    539  1.1  jakllsch 
    540  1.1  jakllsch 
    541  1.1  jakllsch 
    542  1.1  jakllsch UINTN
    543  1.1  jakllsch Print (
    544  1.1  jakllsch     IN CHAR16   *fmt,
    545  1.1  jakllsch     ...
    546  1.1  jakllsch     )
    547  1.1  jakllsch /*++
    548  1.1  jakllsch 
    549  1.1  jakllsch Routine Description:
    550  1.1  jakllsch 
    551  1.1  jakllsch     Prints a formatted unicode string to the default console
    552  1.1  jakllsch 
    553  1.1  jakllsch Arguments:
    554  1.1  jakllsch 
    555  1.1  jakllsch     fmt         - Format string
    556  1.1  jakllsch 
    557  1.1  jakllsch Returns:
    558  1.1  jakllsch 
    559  1.1  jakllsch     Length of string printed to the console
    560  1.1  jakllsch 
    561  1.1  jakllsch --*/
    562  1.1  jakllsch {
    563  1.1  jakllsch     va_list     args;
    564  1.1  jakllsch     UINTN       back;
    565  1.1  jakllsch 
    566  1.1  jakllsch     va_start (args, fmt);
    567  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
    568  1.1  jakllsch     va_end (args);
    569  1.1  jakllsch     return back;
    570  1.1  jakllsch }
    571  1.1  jakllsch 
    572  1.1  jakllsch UINTN
    573  1.1  jakllsch VPrint (
    574  1.1  jakllsch     IN CHAR16   *fmt,
    575  1.1  jakllsch     va_list     args
    576  1.1  jakllsch     )
    577  1.1  jakllsch /*++
    578  1.1  jakllsch 
    579  1.1  jakllsch Routine Description:
    580  1.1  jakllsch 
    581  1.1  jakllsch     Prints a formatted unicode string to the default console using a va_list
    582  1.1  jakllsch 
    583  1.1  jakllsch Arguments:
    584  1.1  jakllsch 
    585  1.1  jakllsch     fmt         - Format string
    586  1.1  jakllsch     args        - va_list
    587  1.1  jakllsch Returns:
    588  1.1  jakllsch 
    589  1.1  jakllsch     Length of string printed to the console
    590  1.1  jakllsch 
    591  1.1  jakllsch --*/
    592  1.1  jakllsch {
    593  1.1  jakllsch     return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
    594  1.1  jakllsch }
    595  1.1  jakllsch 
    596  1.1  jakllsch 
    597  1.1  jakllsch UINTN
    598  1.1  jakllsch PrintAt (
    599  1.1  jakllsch     IN UINTN     Column,
    600  1.1  jakllsch     IN UINTN     Row,
    601  1.1  jakllsch     IN CHAR16    *fmt,
    602  1.1  jakllsch     ...
    603  1.1  jakllsch     )
    604  1.1  jakllsch /*++
    605  1.1  jakllsch 
    606  1.1  jakllsch Routine Description:
    607  1.1  jakllsch 
    608  1.1  jakllsch     Prints a formatted unicode string to the default console, at
    609  1.1  jakllsch     the supplied cursor position
    610  1.1  jakllsch 
    611  1.1  jakllsch Arguments:
    612  1.1  jakllsch 
    613  1.1  jakllsch     Column, Row - The cursor position to print the string at
    614  1.1  jakllsch 
    615  1.1  jakllsch     fmt         - Format string
    616  1.1  jakllsch 
    617  1.1  jakllsch Returns:
    618  1.1  jakllsch 
    619  1.1  jakllsch     Length of string printed to the console
    620  1.1  jakllsch 
    621  1.1  jakllsch --*/
    622  1.1  jakllsch {
    623  1.1  jakllsch     va_list     args;
    624  1.1  jakllsch     UINTN       back;
    625  1.1  jakllsch 
    626  1.1  jakllsch     va_start (args, fmt);
    627  1.1  jakllsch     back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
    628  1.1  jakllsch     va_end (args);
    629  1.1  jakllsch     return back;
    630  1.1  jakllsch }
    631  1.1  jakllsch 
    632  1.1  jakllsch 
    633  1.1  jakllsch UINTN
    634  1.1  jakllsch IPrint (
    635  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE    *Out,
    636  1.1  jakllsch     IN CHAR16                          *fmt,
    637  1.1  jakllsch     ...
    638  1.1  jakllsch     )
    639  1.1  jakllsch /*++
    640  1.1  jakllsch 
    641  1.1  jakllsch Routine Description:
    642  1.1  jakllsch 
    643  1.1  jakllsch     Prints a formatted unicode string to the specified console
    644  1.1  jakllsch 
    645  1.1  jakllsch Arguments:
    646  1.1  jakllsch 
    647  1.1  jakllsch     Out         - The console to print the string too
    648  1.1  jakllsch 
    649  1.1  jakllsch     fmt         - Format string
    650  1.1  jakllsch 
    651  1.1  jakllsch Returns:
    652  1.1  jakllsch 
    653  1.1  jakllsch     Length of string printed to the console
    654  1.1  jakllsch 
    655  1.1  jakllsch --*/
    656  1.1  jakllsch {
    657  1.1  jakllsch     va_list     args;
    658  1.1  jakllsch     UINTN       back;
    659  1.1  jakllsch 
    660  1.1  jakllsch     va_start (args, fmt);
    661  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
    662  1.1  jakllsch     va_end (args);
    663  1.1  jakllsch     return back;
    664  1.1  jakllsch }
    665  1.1  jakllsch 
    666  1.1  jakllsch 
    667  1.1  jakllsch UINTN
    668  1.1  jakllsch IPrintAt (
    669  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE     *Out,
    670  1.1  jakllsch     IN UINTN                            Column,
    671  1.1  jakllsch     IN UINTN                            Row,
    672  1.1  jakllsch     IN CHAR16                           *fmt,
    673  1.1  jakllsch     ...
    674  1.1  jakllsch     )
    675  1.1  jakllsch /*++
    676  1.1  jakllsch 
    677  1.1  jakllsch Routine Description:
    678  1.1  jakllsch 
    679  1.1  jakllsch     Prints a formatted unicode string to the specified console, at
    680  1.1  jakllsch     the supplied cursor position
    681  1.1  jakllsch 
    682  1.1  jakllsch Arguments:
    683  1.1  jakllsch 
    684  1.1  jakllsch     Out         - The console to print the string too
    685  1.1  jakllsch 
    686  1.1  jakllsch     Column, Row - The cursor position to print the string at
    687  1.1  jakllsch 
    688  1.1  jakllsch     fmt         - Format string
    689  1.1  jakllsch 
    690  1.1  jakllsch Returns:
    691  1.1  jakllsch 
    692  1.1  jakllsch     Length of string printed to the console
    693  1.1  jakllsch 
    694  1.1  jakllsch --*/
    695  1.1  jakllsch {
    696  1.1  jakllsch     va_list     args;
    697  1.1  jakllsch     UINTN       back;
    698  1.1  jakllsch 
    699  1.1  jakllsch     va_start (args, fmt);
    700  1.1  jakllsch     back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
    701  1.1  jakllsch     va_end (args);
    702  1.1  jakllsch     return back;
    703  1.1  jakllsch }
    704  1.1  jakllsch 
    705  1.1  jakllsch 
    706  1.1  jakllsch UINTN
    707  1.1  jakllsch _IPrint (
    708  1.1  jakllsch     IN UINTN                            Column,
    709  1.1  jakllsch     IN UINTN                            Row,
    710  1.1  jakllsch     IN SIMPLE_TEXT_OUTPUT_INTERFACE     *Out,
    711  1.1  jakllsch     IN CHAR16                           *fmt,
    712  1.1  jakllsch     IN CHAR8                            *fmta,
    713  1.1  jakllsch     IN va_list                          args
    714  1.1  jakllsch     )
    715  1.1  jakllsch // Display string worker for: Print, PrintAt, IPrint, IPrintAt
    716  1.1  jakllsch {
    717  1.1  jakllsch     PRINT_STATE     ps;
    718  1.1  jakllsch     UINTN            back;
    719  1.1  jakllsch 
    720  1.1  jakllsch     ZeroMem (&ps, sizeof(ps));
    721  1.1  jakllsch     ps.Context = Out;
    722  1.1  jakllsch     ps.Output  = (INTN EFIAPI (*)(VOID *, CHAR16 *)) Out->OutputString;
    723  1.1  jakllsch     ps.SetAttr = (INTN EFIAPI (*)(VOID *, UINTN))  Out->SetAttribute;
    724  1.1  jakllsch     ps.Attr = Out->Mode->Attribute;
    725  1.1  jakllsch 
    726  1.1  jakllsch     back = (ps.Attr >> 4) & 0xF;
    727  1.1  jakllsch     ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
    728  1.1  jakllsch     ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
    729  1.1  jakllsch     ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
    730  1.1  jakllsch 
    731  1.1  jakllsch     if (fmt) {
    732  1.1  jakllsch         ps.fmt.pw = fmt;
    733  1.1  jakllsch     } else {
    734  1.1  jakllsch         ps.fmt.Ascii = TRUE;
    735  1.1  jakllsch         ps.fmt.pc = fmta;
    736  1.1  jakllsch     }
    737  1.1  jakllsch 
    738  1.1  jakllsch     va_copy(ps.args, args);
    739  1.1  jakllsch 
    740  1.1  jakllsch     if (Column != (UINTN) -1) {
    741  1.1  jakllsch         uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
    742  1.1  jakllsch     }
    743  1.1  jakllsch 
    744  1.1  jakllsch     back = _Print (&ps);
    745  1.1  jakllsch     va_end(ps.args);
    746  1.1  jakllsch     return back;
    747  1.1  jakllsch }
    748  1.1  jakllsch 
    749  1.1  jakllsch 
    750  1.1  jakllsch UINTN
    751  1.1  jakllsch APrint (
    752  1.1  jakllsch     IN CHAR8    *fmt,
    753  1.1  jakllsch     ...
    754  1.1  jakllsch     )
    755  1.1  jakllsch /*++
    756  1.1  jakllsch 
    757  1.1  jakllsch Routine Description:
    758  1.1  jakllsch 
    759  1.1  jakllsch     For those whom really can't deal with unicode, a print
    760  1.1  jakllsch     function that takes an ascii format string
    761  1.1  jakllsch 
    762  1.1  jakllsch Arguments:
    763  1.1  jakllsch 
    764  1.1  jakllsch     fmt         - ascii format string
    765  1.1  jakllsch 
    766  1.1  jakllsch Returns:
    767  1.1  jakllsch 
    768  1.1  jakllsch     Length of string printed to the console
    769  1.1  jakllsch 
    770  1.1  jakllsch --*/
    771  1.1  jakllsch 
    772  1.1  jakllsch {
    773  1.1  jakllsch     va_list     args;
    774  1.1  jakllsch     UINTN       back;
    775  1.1  jakllsch 
    776  1.1  jakllsch     va_start (args, fmt);
    777  1.1  jakllsch     back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
    778  1.1  jakllsch     va_end (args);
    779  1.1  jakllsch     return back;
    780  1.1  jakllsch }
    781  1.1  jakllsch 
    782  1.1  jakllsch 
    783  1.1  jakllsch STATIC
    784  1.1  jakllsch VOID
    785  1.1  jakllsch PFLUSH (
    786  1.1  jakllsch     IN OUT PRINT_STATE     *ps
    787  1.1  jakllsch     )
    788  1.1  jakllsch {
    789  1.1  jakllsch     *ps->Pos = 0;
    790  1.1  jakllsch     if (IsLocalPrint(ps->Output))
    791  1.1  jakllsch 	ps->Output(ps->Context, ps->Buffer);
    792  1.1  jakllsch     else
    793  1.1  jakllsch     	uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer);
    794  1.1  jakllsch     ps->Pos = ps->Buffer;
    795  1.1  jakllsch }
    796  1.1  jakllsch 
    797  1.1  jakllsch STATIC
    798  1.1  jakllsch VOID
    799  1.1  jakllsch PSETATTR (
    800  1.1  jakllsch     IN OUT PRINT_STATE  *ps,
    801  1.1  jakllsch     IN UINTN             Attr
    802  1.1  jakllsch     )
    803  1.1  jakllsch {
    804  1.1  jakllsch    PFLUSH (ps);
    805  1.1  jakllsch 
    806  1.1  jakllsch    ps->RestoreAttr = ps->Attr;
    807  1.1  jakllsch    if (ps->SetAttr) {
    808  1.1  jakllsch 	uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr);
    809  1.1  jakllsch    }
    810  1.1  jakllsch 
    811  1.1  jakllsch    ps->Attr = Attr;
    812  1.1  jakllsch }
    813  1.1  jakllsch 
    814  1.1  jakllsch STATIC
    815  1.1  jakllsch VOID
    816  1.1  jakllsch PPUTC (
    817  1.1  jakllsch     IN OUT PRINT_STATE     *ps,
    818  1.1  jakllsch     IN CHAR16              c
    819  1.1  jakllsch     )
    820  1.1  jakllsch {
    821  1.1  jakllsch     // if this is a newline, add a carraige return
    822  1.1  jakllsch     if (c == '\n') {
    823  1.1  jakllsch         PPUTC (ps, '\r');
    824  1.1  jakllsch     }
    825  1.1  jakllsch 
    826  1.1  jakllsch     *ps->Pos = c;
    827  1.1  jakllsch     ps->Pos += 1;
    828  1.1  jakllsch     ps->Len += 1;
    829  1.1  jakllsch 
    830  1.1  jakllsch     // if at the end of the buffer, flush it
    831  1.1  jakllsch     if (ps->Pos >= ps->End) {
    832  1.1  jakllsch         PFLUSH(ps);
    833  1.1  jakllsch     }
    834  1.1  jakllsch }
    835  1.1  jakllsch 
    836  1.1  jakllsch 
    837  1.1  jakllsch STATIC
    838  1.1  jakllsch CHAR16
    839  1.1  jakllsch PGETC (
    840  1.1  jakllsch     IN POINTER      *p
    841  1.1  jakllsch     )
    842  1.1  jakllsch {
    843  1.1  jakllsch     CHAR16      c;
    844  1.1  jakllsch 
    845  1.1  jakllsch     c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
    846  1.1  jakllsch     p->Index += 1;
    847  1.1  jakllsch 
    848  1.1  jakllsch     return  c;
    849  1.1  jakllsch }
    850  1.1  jakllsch 
    851  1.1  jakllsch 
    852  1.1  jakllsch STATIC
    853  1.1  jakllsch VOID
    854  1.1  jakllsch PITEM (
    855  1.1  jakllsch     IN OUT PRINT_STATE  *ps
    856  1.1  jakllsch     )
    857  1.1  jakllsch {
    858  1.1  jakllsch     UINTN               Len, i;
    859  1.1  jakllsch     PRINT_ITEM          *Item;
    860  1.1  jakllsch     CHAR16              c;
    861  1.1  jakllsch 
    862  1.1  jakllsch     // Get the length of the item
    863  1.1  jakllsch     Item = ps->Item;
    864  1.1  jakllsch     Item->Item.Index = 0;
    865  1.1  jakllsch     while (Item->Item.Index < Item->FieldWidth) {
    866  1.1  jakllsch         c = PGETC(&Item->Item);
    867  1.1  jakllsch         if (!c) {
    868  1.1  jakllsch             Item->Item.Index -= 1;
    869  1.1  jakllsch             break;
    870  1.1  jakllsch         }
    871  1.1  jakllsch     }
    872  1.1  jakllsch     Len = Item->Item.Index;
    873  1.1  jakllsch 
    874  1.1  jakllsch     // if there is no item field width, use the items width
    875  1.1  jakllsch     if (Item->FieldWidth == (UINTN) -1) {
    876  1.1  jakllsch         Item->FieldWidth = Len;
    877  1.1  jakllsch     }
    878  1.1  jakllsch 
    879  1.1  jakllsch     // if item is larger then width, update width
    880  1.1  jakllsch     if (Len > Item->Width) {
    881  1.1  jakllsch         Item->Width = Len;
    882  1.1  jakllsch     }
    883  1.1  jakllsch 
    884  1.1  jakllsch 
    885  1.1  jakllsch     // if pad field before, add pad char
    886  1.1  jakllsch     if (Item->PadBefore) {
    887  1.1  jakllsch         for (i=Item->Width; i < Item->FieldWidth; i+=1) {
    888  1.1  jakllsch             PPUTC (ps, ' ');
    889  1.1  jakllsch         }
    890  1.1  jakllsch     }
    891  1.1  jakllsch 
    892  1.1  jakllsch     // pad item
    893  1.1  jakllsch     for (i=Len; i < Item->Width; i++) {
    894  1.1  jakllsch         PPUTC (ps, Item->Pad);
    895  1.1  jakllsch     }
    896  1.1  jakllsch 
    897  1.1  jakllsch     // add the item
    898  1.1  jakllsch     Item->Item.Index=0;
    899  1.1  jakllsch     while (Item->Item.Index < Len) {
    900  1.1  jakllsch         PPUTC (ps, PGETC(&Item->Item));
    901  1.1  jakllsch     }
    902  1.1  jakllsch 
    903  1.1  jakllsch     // If pad at the end, add pad char
    904  1.1  jakllsch     if (!Item->PadBefore) {
    905  1.1  jakllsch         for (i=Item->Width; i < Item->FieldWidth; i+=1) {
    906  1.1  jakllsch             PPUTC (ps, ' ');
    907  1.1  jakllsch         }
    908  1.1  jakllsch     }
    909  1.1  jakllsch }
    910  1.1  jakllsch 
    911  1.1  jakllsch 
    912  1.1  jakllsch STATIC
    913  1.1  jakllsch UINTN
    914  1.1  jakllsch _Print (
    915  1.1  jakllsch     IN PRINT_STATE     *ps
    916  1.1  jakllsch     )
    917  1.1  jakllsch /*++
    918  1.1  jakllsch 
    919  1.1  jakllsch Routine Description:
    920  1.1  jakllsch 
    921  1.1  jakllsch     %w.lF   -   w = width
    922  1.1  jakllsch                 l = field width
    923  1.1  jakllsch                 F = format of arg
    924  1.1  jakllsch 
    925  1.1  jakllsch   Args F:
    926  1.1  jakllsch     0       -   pad with zeros
    927  1.1  jakllsch     -       -   justify on left (default is on right)
    928  1.1  jakllsch     ,       -   add comma's to field
    929  1.1  jakllsch     *       -   width provided on stack
    930  1.1  jakllsch     n       -   Set output attribute to normal (for this field only)
    931  1.1  jakllsch     h       -   Set output attribute to highlight (for this field only)
    932  1.1  jakllsch     e       -   Set output attribute to error (for this field only)
    933  1.1  jakllsch     l       -   Value is 64 bits
    934  1.1  jakllsch 
    935  1.1  jakllsch     a       -   ascii string
    936  1.1  jakllsch     s       -   unicode string
    937  1.1  jakllsch     X       -   fixed 8 byte value in hex
    938  1.1  jakllsch     x       -   hex value
    939  1.1  jakllsch     d       -   value as decimal
    940  1.1  jakllsch     c       -   Unicode char
    941  1.1  jakllsch     t       -   EFI time structure
    942  1.1  jakllsch     g       -   Pointer to GUID
    943  1.1  jakllsch     r       -   EFI status code (result code)
    944  1.1  jakllsch 
    945  1.1  jakllsch     N       -   Set output attribute to normal
    946  1.1  jakllsch     H       -   Set output attribute to highlight
    947  1.1  jakllsch     E       -   Set output attribute to error
    948  1.1  jakllsch     %       -   Print a %
    949  1.1  jakllsch 
    950  1.1  jakllsch Arguments:
    951  1.1  jakllsch 
    952  1.1  jakllsch     SystemTable     - The system table
    953  1.1  jakllsch 
    954  1.1  jakllsch Returns:
    955  1.1  jakllsch 
    956  1.1  jakllsch     Number of charactors written
    957  1.1  jakllsch 
    958  1.1  jakllsch --*/
    959  1.1  jakllsch {
    960  1.1  jakllsch     CHAR16          c;
    961  1.1  jakllsch     UINTN           Attr;
    962  1.1  jakllsch     PRINT_ITEM      Item;
    963  1.1  jakllsch     CHAR16          Buffer[PRINT_STRING_LEN];
    964  1.1  jakllsch 
    965  1.1  jakllsch     ps->Len = 0;
    966  1.1  jakllsch     ps->Buffer = Buffer;
    967  1.1  jakllsch     ps->Pos = Buffer;
    968  1.1  jakllsch     ps->End = Buffer + PRINT_STRING_LEN - 1;
    969  1.1  jakllsch     ps->Item = &Item;
    970  1.1  jakllsch 
    971  1.1  jakllsch     ps->fmt.Index = 0;
    972  1.1  jakllsch     while ((c = PGETC(&ps->fmt))) {
    973  1.1  jakllsch 
    974  1.1  jakllsch         if (c != '%') {
    975  1.1  jakllsch             PPUTC ( ps, c );
    976  1.1  jakllsch             continue;
    977  1.1  jakllsch         }
    978  1.1  jakllsch 
    979  1.1  jakllsch         // setup for new item
    980  1.1  jakllsch         Item.FieldWidth = (UINTN) -1;
    981  1.1  jakllsch         Item.Width = 0;
    982  1.1  jakllsch         Item.WidthParse = &Item.Width;
    983  1.1  jakllsch         Item.Pad = ' ';
    984  1.1  jakllsch         Item.PadBefore = TRUE;
    985  1.1  jakllsch         Item.Comma = FALSE;
    986  1.1  jakllsch         Item.Long = FALSE;
    987  1.1  jakllsch         Item.Item.Ascii = FALSE;
    988  1.1  jakllsch         Item.Item.pw = NULL;
    989  1.1  jakllsch         ps->RestoreAttr = 0;
    990  1.1  jakllsch         Attr = 0;
    991  1.1  jakllsch 
    992  1.1  jakllsch         while ((c = PGETC(&ps->fmt))) {
    993  1.1  jakllsch 
    994  1.1  jakllsch             switch (c) {
    995  1.1  jakllsch 
    996  1.1  jakllsch             case '%':
    997  1.1  jakllsch                 //
    998  1.1  jakllsch                 // %% -> %
    999  1.1  jakllsch                 //
   1000  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1001  1.1  jakllsch                 Item.Item.pw[0] = '%';
   1002  1.1  jakllsch                 Item.Item.pw[1] = 0;
   1003  1.1  jakllsch                 break;
   1004  1.1  jakllsch 
   1005  1.1  jakllsch             case '0':
   1006  1.1  jakllsch                 Item.Pad = '0';
   1007  1.1  jakllsch                 break;
   1008  1.1  jakllsch 
   1009  1.1  jakllsch             case '-':
   1010  1.1  jakllsch                 Item.PadBefore = FALSE;
   1011  1.1  jakllsch                 break;
   1012  1.1  jakllsch 
   1013  1.1  jakllsch             case ',':
   1014  1.1  jakllsch                 Item.Comma = TRUE;
   1015  1.1  jakllsch                 break;
   1016  1.1  jakllsch 
   1017  1.1  jakllsch             case '.':
   1018  1.1  jakllsch                 Item.WidthParse = &Item.FieldWidth;
   1019  1.1  jakllsch                 break;
   1020  1.1  jakllsch 
   1021  1.1  jakllsch             case '*':
   1022  1.1  jakllsch                 *Item.WidthParse = va_arg(ps->args, UINTN);
   1023  1.1  jakllsch                 break;
   1024  1.1  jakllsch 
   1025  1.1  jakllsch             case '1':
   1026  1.1  jakllsch             case '2':
   1027  1.1  jakllsch             case '3':
   1028  1.1  jakllsch             case '4':
   1029  1.1  jakllsch             case '5':
   1030  1.1  jakllsch             case '6':
   1031  1.1  jakllsch             case '7':
   1032  1.1  jakllsch             case '8':
   1033  1.1  jakllsch             case '9':
   1034  1.1  jakllsch                 *Item.WidthParse = 0;
   1035  1.1  jakllsch                 do {
   1036  1.1  jakllsch                     *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
   1037  1.1  jakllsch                     c = PGETC(&ps->fmt);
   1038  1.1  jakllsch                 } while (c >= '0'  &&  c <= '9') ;
   1039  1.1  jakllsch                 ps->fmt.Index -= 1;
   1040  1.1  jakllsch                 break;
   1041  1.1  jakllsch 
   1042  1.1  jakllsch             case 'a':
   1043  1.1  jakllsch                 Item.Item.pc = va_arg(ps->args, CHAR8 *);
   1044  1.1  jakllsch                 Item.Item.Ascii = TRUE;
   1045  1.1  jakllsch                 if (!Item.Item.pc) {
   1046  1.1  jakllsch                     Item.Item.pc = (CHAR8 *)"(null)";
   1047  1.1  jakllsch                 }
   1048  1.1  jakllsch                 break;
   1049  1.1  jakllsch 
   1050  1.1  jakllsch             case 's':
   1051  1.1  jakllsch                 Item.Item.pw = va_arg(ps->args, CHAR16 *);
   1052  1.1  jakllsch                 if (!Item.Item.pw) {
   1053  1.1  jakllsch                     Item.Item.pw = L"(null)";
   1054  1.1  jakllsch                 }
   1055  1.1  jakllsch                 break;
   1056  1.1  jakllsch 
   1057  1.1  jakllsch             case 'c':
   1058  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1059  1.1  jakllsch                 Item.Item.pw[0] = (CHAR16) va_arg(ps->args, UINTN);
   1060  1.1  jakllsch                 Item.Item.pw[1] = 0;
   1061  1.1  jakllsch                 break;
   1062  1.1  jakllsch 
   1063  1.1  jakllsch             case 'l':
   1064  1.1  jakllsch                 Item.Long = TRUE;
   1065  1.1  jakllsch                 break;
   1066  1.1  jakllsch 
   1067  1.1  jakllsch             case 'X':
   1068  1.1  jakllsch                 Item.Width = Item.Long ? 16 : 8;
   1069  1.1  jakllsch                 Item.Pad = '0';
   1070  1.1  jakllsch             case 'x':
   1071  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1072  1.1  jakllsch                 ValueToHex (
   1073  1.1  jakllsch                     Item.Item.pw,
   1074  1.1  jakllsch                     Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
   1075  1.1  jakllsch                     );
   1076  1.1  jakllsch 
   1077  1.1  jakllsch                 break;
   1078  1.1  jakllsch 
   1079  1.1  jakllsch 
   1080  1.1  jakllsch             case 'g':
   1081  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1082  1.1  jakllsch                 GuidToString (Item.Item.pw, va_arg(ps->args, EFI_GUID *));
   1083  1.1  jakllsch                 break;
   1084  1.1  jakllsch 
   1085  1.1  jakllsch             case 'd':
   1086  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1087  1.1  jakllsch                 ValueToString (
   1088  1.1  jakllsch                     Item.Item.pw,
   1089  1.1  jakllsch                     Item.Comma,
   1090  1.1  jakllsch                     Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
   1091  1.1  jakllsch                     );
   1092  1.1  jakllsch                 break
   1093  1.1  jakllsch                     ;
   1094  1.1  jakllsch             case 't':
   1095  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1096  1.1  jakllsch                 TimeToString (Item.Item.pw, va_arg(ps->args, EFI_TIME *));
   1097  1.1  jakllsch                 break;
   1098  1.1  jakllsch 
   1099  1.1  jakllsch             case 'r':
   1100  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1101  1.1  jakllsch                 StatusToString (Item.Item.pw, va_arg(ps->args, EFI_STATUS));
   1102  1.1  jakllsch                 break;
   1103  1.1  jakllsch 
   1104  1.1  jakllsch             case 'n':
   1105  1.1  jakllsch                 PSETATTR(ps, ps->AttrNorm);
   1106  1.1  jakllsch                 break;
   1107  1.1  jakllsch 
   1108  1.1  jakllsch             case 'h':
   1109  1.1  jakllsch                 PSETATTR(ps, ps->AttrHighlight);
   1110  1.1  jakllsch                 break;
   1111  1.1  jakllsch 
   1112  1.1  jakllsch             case 'e':
   1113  1.1  jakllsch                 PSETATTR(ps, ps->AttrError);
   1114  1.1  jakllsch                 break;
   1115  1.1  jakllsch 
   1116  1.1  jakllsch             case 'N':
   1117  1.1  jakllsch                 Attr = ps->AttrNorm;
   1118  1.1  jakllsch                 break;
   1119  1.1  jakllsch 
   1120  1.1  jakllsch             case 'H':
   1121  1.1  jakllsch                 Attr = ps->AttrHighlight;
   1122  1.1  jakllsch                 break;
   1123  1.1  jakllsch 
   1124  1.1  jakllsch             case 'E':
   1125  1.1  jakllsch                 Attr = ps->AttrError;
   1126  1.1  jakllsch                 break;
   1127  1.1  jakllsch 
   1128  1.1  jakllsch             default:
   1129  1.1  jakllsch                 Item.Item.pw = Item.Scratch;
   1130  1.1  jakllsch                 Item.Item.pw[0] = '?';
   1131  1.1  jakllsch                 Item.Item.pw[1] = 0;
   1132  1.1  jakllsch                 break;
   1133  1.1  jakllsch             }
   1134  1.1  jakllsch 
   1135  1.1  jakllsch             // if we have an Item
   1136  1.1  jakllsch             if (Item.Item.pw) {
   1137  1.1  jakllsch                 PITEM (ps);
   1138  1.1  jakllsch                 break;
   1139  1.1  jakllsch             }
   1140  1.1  jakllsch 
   1141  1.1  jakllsch             // if we have an Attr set
   1142  1.1  jakllsch             if (Attr) {
   1143  1.1  jakllsch                 PSETATTR(ps, Attr);
   1144  1.1  jakllsch                 ps->RestoreAttr = 0;
   1145  1.1  jakllsch                 break;
   1146  1.1  jakllsch             }
   1147  1.1  jakllsch         }
   1148  1.1  jakllsch 
   1149  1.1  jakllsch         if (ps->RestoreAttr) {
   1150  1.1  jakllsch             PSETATTR(ps, ps->RestoreAttr);
   1151  1.1  jakllsch         }
   1152  1.1  jakllsch     }
   1153  1.1  jakllsch 
   1154  1.1  jakllsch     // Flush buffer
   1155  1.1  jakllsch     PFLUSH (ps);
   1156  1.1  jakllsch     return ps->Len;
   1157  1.1  jakllsch }
   1158  1.1  jakllsch 
   1159  1.1  jakllsch STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
   1160  1.1  jakllsch                       '8','9','A','B','C','D','E','F'};
   1161  1.1  jakllsch 
   1162  1.1  jakllsch VOID
   1163  1.1  jakllsch ValueToHex (
   1164  1.1  jakllsch     IN CHAR16   *Buffer,
   1165  1.1  jakllsch     IN UINT64   v
   1166  1.1  jakllsch     )
   1167  1.1  jakllsch {
   1168  1.1  jakllsch     CHAR8           str[30], *p1;
   1169  1.1  jakllsch     CHAR16          *p2;
   1170  1.1  jakllsch 
   1171  1.1  jakllsch     if (!v) {
   1172  1.1  jakllsch         Buffer[0] = '0';
   1173  1.1  jakllsch         Buffer[1] = 0;
   1174  1.1  jakllsch         return ;
   1175  1.1  jakllsch     }
   1176  1.1  jakllsch 
   1177  1.1  jakllsch     p1 = str;
   1178  1.1  jakllsch     p2 = Buffer;
   1179  1.1  jakllsch 
   1180  1.1  jakllsch     while (v) {
   1181  1.1  jakllsch         *(p1++) = Hex[v & 0xf];
   1182  1.1  jakllsch         v = RShiftU64 (v, 4);
   1183  1.1  jakllsch     }
   1184  1.1  jakllsch 
   1185  1.1  jakllsch     while (p1 != str) {
   1186  1.1  jakllsch         *(p2++) = *(--p1);
   1187  1.1  jakllsch     }
   1188  1.1  jakllsch     *p2 = 0;
   1189  1.1  jakllsch }
   1190  1.1  jakllsch 
   1191  1.1  jakllsch 
   1192  1.1  jakllsch VOID
   1193  1.1  jakllsch ValueToString (
   1194  1.1  jakllsch     IN CHAR16   *Buffer,
   1195  1.1  jakllsch     IN BOOLEAN  Comma,
   1196  1.1  jakllsch     IN INT64    v
   1197  1.1  jakllsch     )
   1198  1.1  jakllsch {
   1199  1.1  jakllsch     STATIC CHAR8 ca[] = {  3, 1, 2 };
   1200  1.1  jakllsch     CHAR8        str[40], *p1;
   1201  1.1  jakllsch     CHAR16       *p2;
   1202  1.1  jakllsch     UINTN        c, r;
   1203  1.1  jakllsch 
   1204  1.1  jakllsch     if (!v) {
   1205  1.1  jakllsch         Buffer[0] = '0';
   1206  1.1  jakllsch         Buffer[1] = 0;
   1207  1.1  jakllsch         return ;
   1208  1.1  jakllsch     }
   1209  1.1  jakllsch 
   1210  1.1  jakllsch     p1 = str;
   1211  1.1  jakllsch     p2 = Buffer;
   1212  1.1  jakllsch 
   1213  1.1  jakllsch     if (v < 0) {
   1214  1.1  jakllsch         *(p2++) = '-';
   1215  1.1  jakllsch         v = -v;
   1216  1.1  jakllsch     }
   1217  1.1  jakllsch 
   1218  1.1  jakllsch     while (v) {
   1219  1.1  jakllsch         v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
   1220  1.1  jakllsch         *(p1++) = (CHAR8)r + '0';
   1221  1.1  jakllsch     }
   1222  1.1  jakllsch 
   1223  1.1  jakllsch     c = (Comma ? ca[(p1 - str) % 3] : 999) + 1;
   1224  1.1  jakllsch     while (p1 != str) {
   1225  1.1  jakllsch 
   1226  1.1  jakllsch         c -= 1;
   1227  1.1  jakllsch         if (!c) {
   1228  1.1  jakllsch             *(p2++) = ',';
   1229  1.1  jakllsch             c = 3;
   1230  1.1  jakllsch         }
   1231  1.1  jakllsch 
   1232  1.1  jakllsch         *(p2++) = *(--p1);
   1233  1.1  jakllsch     }
   1234  1.1  jakllsch     *p2 = 0;
   1235  1.1  jakllsch }
   1236  1.1  jakllsch 
   1237  1.1  jakllsch VOID
   1238  1.1  jakllsch TimeToString (
   1239  1.1  jakllsch     OUT CHAR16      *Buffer,
   1240  1.1  jakllsch     IN EFI_TIME     *Time
   1241  1.1  jakllsch     )
   1242  1.1  jakllsch {
   1243  1.1  jakllsch     UINTN       Hour, Year;
   1244  1.1  jakllsch     CHAR16      AmPm;
   1245  1.1  jakllsch 
   1246  1.1  jakllsch     AmPm = 'a';
   1247  1.1  jakllsch     Hour = Time->Hour;
   1248  1.1  jakllsch     if (Time->Hour == 0) {
   1249  1.1  jakllsch         Hour = 12;
   1250  1.1  jakllsch     } else if (Time->Hour >= 12) {
   1251  1.1  jakllsch         AmPm = 'p';
   1252  1.1  jakllsch         if (Time->Hour >= 13) {
   1253  1.1  jakllsch             Hour -= 12;
   1254  1.1  jakllsch         }
   1255  1.1  jakllsch     }
   1256  1.1  jakllsch 
   1257  1.1  jakllsch     Year = Time->Year % 100;
   1258  1.1  jakllsch 
   1259  1.1  jakllsch     // bugbug: for now just print it any old way
   1260  1.1  jakllsch     SPrint (Buffer, 0, L"%02d/%02d/%02d  %02d:%02d%c",
   1261  1.1  jakllsch         Time->Month,
   1262  1.1  jakllsch         Time->Day,
   1263  1.1  jakllsch         Year,
   1264  1.1  jakllsch         Hour,
   1265  1.1  jakllsch         Time->Minute,
   1266  1.1  jakllsch         AmPm
   1267  1.1  jakllsch         );
   1268  1.1  jakllsch }
   1269  1.1  jakllsch 
   1270  1.1  jakllsch 
   1271  1.1  jakllsch 
   1272  1.1  jakllsch 
   1273  1.1  jakllsch VOID
   1274  1.1  jakllsch DumpHex (
   1275  1.1  jakllsch     IN UINTN        Indent,
   1276  1.1  jakllsch     IN UINTN        Offset,
   1277  1.1  jakllsch     IN UINTN        DataSize,
   1278  1.1  jakllsch     IN VOID         *UserData
   1279  1.1  jakllsch     )
   1280  1.1  jakllsch {
   1281  1.1  jakllsch     CHAR8           *Data, Val[50], Str[20], c;
   1282  1.1  jakllsch     UINTN           Size, Index;
   1283  1.1  jakllsch 
   1284  1.1  jakllsch     UINTN           ScreenCount;
   1285  1.1  jakllsch     UINTN           TempColumn;
   1286  1.1  jakllsch     UINTN           ScreenSize;
   1287  1.1  jakllsch     CHAR16          ReturnStr[1];
   1288  1.1  jakllsch 
   1289  1.1  jakllsch 
   1290  1.1  jakllsch     uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
   1291  1.1  jakllsch     ScreenCount = 0;
   1292  1.1  jakllsch     ScreenSize -= 2;
   1293  1.1  jakllsch 
   1294  1.1  jakllsch     Data = UserData;
   1295  1.1  jakllsch     while (DataSize) {
   1296  1.1  jakllsch         Size = 16;
   1297  1.1  jakllsch         if (Size > DataSize) {
   1298  1.1  jakllsch             Size = DataSize;
   1299  1.1  jakllsch         }
   1300  1.1  jakllsch 
   1301  1.1  jakllsch         for (Index=0; Index < Size; Index += 1) {
   1302  1.1  jakllsch             c = Data[Index];
   1303  1.1  jakllsch             Val[Index*3+0] = Hex[c>>4];
   1304  1.1  jakllsch             Val[Index*3+1] = Hex[c&0xF];
   1305  1.1  jakllsch             Val[Index*3+2] = (Index == 7)?'-':' ';
   1306  1.1  jakllsch             Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
   1307  1.1  jakllsch         }
   1308  1.1  jakllsch 
   1309  1.1  jakllsch         Val[Index*3] = 0;
   1310  1.1  jakllsch         Str[Index] = 0;
   1311  1.1  jakllsch         Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
   1312  1.1  jakllsch 
   1313  1.1  jakllsch         Data += Size;
   1314  1.1  jakllsch         Offset += Size;
   1315  1.1  jakllsch         DataSize -= Size;
   1316  1.1  jakllsch 
   1317  1.1  jakllsch         ScreenCount++;
   1318  1.1  jakllsch         if (ScreenCount >= ScreenSize && ScreenSize != 0) {
   1319  1.1  jakllsch             //
   1320  1.1  jakllsch             // If ScreenSize == 0 we have the console redirected so don't
   1321  1.1  jakllsch             //  block updates
   1322  1.1  jakllsch             //
   1323  1.1  jakllsch             ScreenCount = 0;
   1324  1.1  jakllsch             Print (L"Press Enter to continue :");
   1325  1.1  jakllsch             Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
   1326  1.1  jakllsch             Print (L"\n");
   1327  1.1  jakllsch         }
   1328  1.1  jakllsch 
   1329  1.1  jakllsch     }
   1330  1.1  jakllsch }
   1331