1530d68baSNigel Croxon /*++ 2530d68baSNigel Croxon 3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation 4530d68baSNigel Croxon 5530d68baSNigel Croxon Module Name: 6530d68baSNigel Croxon 7530d68baSNigel Croxon print.c 8530d68baSNigel Croxon 9530d68baSNigel Croxon Abstract: 10530d68baSNigel Croxon 11530d68baSNigel Croxon 12530d68baSNigel Croxon 13530d68baSNigel Croxon 14530d68baSNigel Croxon Revision History 15530d68baSNigel Croxon 16530d68baSNigel Croxon --*/ 17530d68baSNigel Croxon 18530d68baSNigel Croxon #include "lib.h" 19530d68baSNigel Croxon #include "efistdarg.h" // !!! 20530d68baSNigel Croxon 21530d68baSNigel Croxon // 22530d68baSNigel Croxon // Declare runtime functions 23530d68baSNigel Croxon // 24530d68baSNigel Croxon 25530d68baSNigel Croxon #ifdef RUNTIME_CODE 26530d68baSNigel Croxon #ifndef __GNUC__ 27530d68baSNigel Croxon #pragma RUNTIME_CODE(DbgPrint) 28530d68baSNigel Croxon 29530d68baSNigel Croxon // For debugging.. 30530d68baSNigel Croxon 31530d68baSNigel Croxon /* 32530d68baSNigel Croxon #pragma RUNTIME_CODE(_Print) 33530d68baSNigel Croxon #pragma RUNTIME_CODE(PFLUSH) 34530d68baSNigel Croxon #pragma RUNTIME_CODE(PSETATTR) 35530d68baSNigel Croxon #pragma RUNTIME_CODE(PPUTC) 36530d68baSNigel Croxon #pragma RUNTIME_CODE(PGETC) 37530d68baSNigel Croxon #pragma RUNTIME_CODE(PITEM) 38530d68baSNigel Croxon #pragma RUNTIME_CODE(ValueToHex) 39530d68baSNigel Croxon #pragma RUNTIME_CODE(ValueToString) 40530d68baSNigel Croxon #pragma RUNTIME_CODE(TimeToString) 41530d68baSNigel Croxon */ 42530d68baSNigel Croxon 43530d68baSNigel Croxon #endif /* !defined(__GNUC__) */ 44530d68baSNigel Croxon #endif 45530d68baSNigel Croxon 46530d68baSNigel Croxon // 47530d68baSNigel Croxon // 48530d68baSNigel Croxon // 49530d68baSNigel Croxon 50530d68baSNigel Croxon 51530d68baSNigel Croxon #define PRINT_STRING_LEN 200 52530d68baSNigel Croxon #define PRINT_ITEM_BUFFER_LEN 100 53530d68baSNigel Croxon 54530d68baSNigel Croxon typedef struct { 55530d68baSNigel Croxon BOOLEAN Ascii; 56530d68baSNigel Croxon UINTN Index; 57530d68baSNigel Croxon union { 58530d68baSNigel Croxon CHAR16 *pw; 59530d68baSNigel Croxon CHAR8 *pc; 60530d68baSNigel Croxon } un; 61530d68baSNigel Croxon } POINTER; 62530d68baSNigel Croxon 63530d68baSNigel Croxon #define pw un.pw 64530d68baSNigel Croxon #define pc un.pc 65530d68baSNigel Croxon 66530d68baSNigel Croxon typedef struct _pitem { 67530d68baSNigel Croxon 68530d68baSNigel Croxon POINTER Item; 69530d68baSNigel Croxon CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN]; 70530d68baSNigel Croxon UINTN Width; 71530d68baSNigel Croxon UINTN FieldWidth; 72530d68baSNigel Croxon UINTN *WidthParse; 73530d68baSNigel Croxon CHAR16 Pad; 74530d68baSNigel Croxon BOOLEAN PadBefore; 75530d68baSNigel Croxon BOOLEAN Comma; 76530d68baSNigel Croxon BOOLEAN Long; 77530d68baSNigel Croxon } PRINT_ITEM; 78530d68baSNigel Croxon 79530d68baSNigel Croxon 80530d68baSNigel Croxon typedef struct _pstate { 81530d68baSNigel Croxon // Input 82530d68baSNigel Croxon POINTER fmt; 83530d68baSNigel Croxon va_list args; 84530d68baSNigel Croxon 85530d68baSNigel Croxon // Output 86530d68baSNigel Croxon CHAR16 *Buffer; 87530d68baSNigel Croxon CHAR16 *End; 88530d68baSNigel Croxon CHAR16 *Pos; 89530d68baSNigel Croxon UINTN Len; 90530d68baSNigel Croxon 91530d68baSNigel Croxon UINTN Attr; 92530d68baSNigel Croxon UINTN RestoreAttr; 93530d68baSNigel Croxon 94530d68baSNigel Croxon UINTN AttrNorm; 95530d68baSNigel Croxon UINTN AttrHighlight; 96530d68baSNigel Croxon UINTN AttrError; 97530d68baSNigel Croxon 9809027207SNigel Croxon INTN (EFIAPI *Output)(VOID *context, CHAR16 *str); 9909027207SNigel Croxon INTN (EFIAPI *SetAttr)(VOID *context, UINTN attr); 100530d68baSNigel Croxon VOID *Context; 101530d68baSNigel Croxon 102530d68baSNigel Croxon // Current item being formatted 103530d68baSNigel Croxon struct _pitem *Item; 104530d68baSNigel Croxon } PRINT_STATE; 105530d68baSNigel Croxon 106530d68baSNigel Croxon // 107530d68baSNigel Croxon // Internal fucntions 108530d68baSNigel Croxon // 109530d68baSNigel Croxon 110530d68baSNigel Croxon STATIC 111530d68baSNigel Croxon UINTN 112530d68baSNigel Croxon _Print ( 113530d68baSNigel Croxon IN PRINT_STATE *ps 114530d68baSNigel Croxon ); 115530d68baSNigel Croxon 116530d68baSNigel Croxon STATIC 117530d68baSNigel Croxon UINTN 118530d68baSNigel Croxon _IPrint ( 119530d68baSNigel Croxon IN UINTN Column, 120530d68baSNigel Croxon IN UINTN Row, 121530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, 122530d68baSNigel Croxon IN CHAR16 *fmt, 123530d68baSNigel Croxon IN CHAR8 *fmta, 124530d68baSNigel Croxon IN va_list args 125530d68baSNigel Croxon ); 126530d68baSNigel Croxon 127530d68baSNigel Croxon STATIC 128530d68baSNigel Croxon INTN EFIAPI 129530d68baSNigel Croxon _DbgOut ( 130530d68baSNigel Croxon IN VOID *Context, 131530d68baSNigel Croxon IN CHAR16 *Buffer 132530d68baSNigel Croxon ); 133530d68baSNigel Croxon 134530d68baSNigel Croxon STATIC 135530d68baSNigel Croxon VOID 136530d68baSNigel Croxon PFLUSH ( 137530d68baSNigel Croxon IN OUT PRINT_STATE *ps 138530d68baSNigel Croxon ); 139530d68baSNigel Croxon 140530d68baSNigel Croxon STATIC 141530d68baSNigel Croxon VOID 142530d68baSNigel Croxon PPUTC ( 143530d68baSNigel Croxon IN OUT PRINT_STATE *ps, 144530d68baSNigel Croxon IN CHAR16 c 145530d68baSNigel Croxon ); 146530d68baSNigel Croxon 147530d68baSNigel Croxon STATIC 148530d68baSNigel Croxon VOID 149530d68baSNigel Croxon PITEM ( 150530d68baSNigel Croxon IN OUT PRINT_STATE *ps 151530d68baSNigel Croxon ); 152530d68baSNigel Croxon 153530d68baSNigel Croxon STATIC 154530d68baSNigel Croxon CHAR16 155530d68baSNigel Croxon PGETC ( 156530d68baSNigel Croxon IN POINTER *p 157530d68baSNigel Croxon ); 158530d68baSNigel Croxon 159530d68baSNigel Croxon STATIC 160530d68baSNigel Croxon VOID 161530d68baSNigel Croxon PSETATTR ( 162530d68baSNigel Croxon IN OUT PRINT_STATE *ps, 163530d68baSNigel Croxon IN UINTN Attr 164530d68baSNigel Croxon ); 165530d68baSNigel Croxon 166530d68baSNigel Croxon // 167530d68baSNigel Croxon // 168530d68baSNigel Croxon // 169530d68baSNigel Croxon 170530d68baSNigel Croxon INTN EFIAPI 171530d68baSNigel Croxon _SPrint ( 172530d68baSNigel Croxon IN VOID *Context, 173530d68baSNigel Croxon IN CHAR16 *Buffer 174530d68baSNigel Croxon ); 175530d68baSNigel Croxon 176530d68baSNigel Croxon INTN EFIAPI 177530d68baSNigel Croxon _PoolPrint ( 178530d68baSNigel Croxon IN VOID *Context, 179530d68baSNigel Croxon IN CHAR16 *Buffer 180530d68baSNigel Croxon ); 181530d68baSNigel Croxon 182530d68baSNigel Croxon INTN 183530d68baSNigel Croxon DbgPrint ( 184530d68baSNigel Croxon IN INTN mask, 185530d68baSNigel Croxon IN CHAR8 *fmt, 186530d68baSNigel Croxon ... 187530d68baSNigel Croxon ) 188530d68baSNigel Croxon /*++ 189530d68baSNigel Croxon 190530d68baSNigel Croxon Routine Description: 191530d68baSNigel Croxon 192530d68baSNigel Croxon Prints a formatted unicode string to the default StandardError console 193530d68baSNigel Croxon 194530d68baSNigel Croxon Arguments: 195530d68baSNigel Croxon 196530d68baSNigel Croxon mask - Bit mask of debug string. If a bit is set in the 197530d68baSNigel Croxon mask that is also set in EFIDebug the string is 198530d68baSNigel Croxon printed; otherwise, the string is not printed 199530d68baSNigel Croxon 200530d68baSNigel Croxon fmt - Format string 201530d68baSNigel Croxon 202530d68baSNigel Croxon Returns: 203530d68baSNigel Croxon 204530d68baSNigel Croxon Length of string printed to the StandardError console 205530d68baSNigel Croxon 206530d68baSNigel Croxon --*/ 207530d68baSNigel Croxon { 208530d68baSNigel Croxon SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut; 209530d68baSNigel Croxon PRINT_STATE ps; 210530d68baSNigel Croxon va_list args; 211530d68baSNigel Croxon UINTN back; 212530d68baSNigel Croxon UINTN attr; 213530d68baSNigel Croxon UINTN SavedAttribute; 214530d68baSNigel Croxon 215530d68baSNigel Croxon 216530d68baSNigel Croxon if (!(EFIDebug & mask)) { 217530d68baSNigel Croxon return 0; 218530d68baSNigel Croxon } 219530d68baSNigel Croxon 220530d68baSNigel Croxon va_start (args, fmt); 221530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps)); 222530d68baSNigel Croxon 223530d68baSNigel Croxon ps.Output = _DbgOut; 224530d68baSNigel Croxon ps.fmt.Ascii = TRUE; 225530d68baSNigel Croxon ps.fmt.pc = fmt; 226530d68baSNigel Croxon va_copy(ps.args, args); 227530d68baSNigel Croxon ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED); 228530d68baSNigel Croxon 229530d68baSNigel Croxon DbgOut = LibRuntimeDebugOut; 230530d68baSNigel Croxon 231530d68baSNigel Croxon if (!DbgOut) { 232530d68baSNigel Croxon DbgOut = ST->StdErr; 233530d68baSNigel Croxon } 234530d68baSNigel Croxon 235530d68baSNigel Croxon if (DbgOut) { 236530d68baSNigel Croxon ps.Attr = DbgOut->Mode->Attribute; 237530d68baSNigel Croxon ps.Context = DbgOut; 23809027207SNigel Croxon ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) DbgOut->SetAttribute; 239530d68baSNigel Croxon } 240530d68baSNigel Croxon 241530d68baSNigel Croxon SavedAttribute = ps.Attr; 242530d68baSNigel Croxon 243530d68baSNigel Croxon back = (ps.Attr >> 4) & 0xf; 244530d68baSNigel Croxon ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back); 245530d68baSNigel Croxon ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back); 246530d68baSNigel Croxon ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back); 247530d68baSNigel Croxon 248530d68baSNigel Croxon attr = ps.AttrNorm; 249530d68baSNigel Croxon 250530d68baSNigel Croxon if (mask & D_WARN) { 251530d68baSNigel Croxon attr = ps.AttrHighlight; 252530d68baSNigel Croxon } 253530d68baSNigel Croxon 254530d68baSNigel Croxon if (mask & D_ERROR) { 255530d68baSNigel Croxon attr = ps.AttrError; 256530d68baSNigel Croxon } 257530d68baSNigel Croxon 258530d68baSNigel Croxon if (ps.SetAttr) { 259530d68baSNigel Croxon ps.Attr = attr; 260530d68baSNigel Croxon uefi_call_wrapper(ps.SetAttr, 2, ps.Context, attr); 261530d68baSNigel Croxon } 262530d68baSNigel Croxon 263530d68baSNigel Croxon _Print (&ps); 264530d68baSNigel Croxon 265530d68baSNigel Croxon va_end (ps.args); 266530d68baSNigel Croxon va_end (args); 267530d68baSNigel Croxon 268530d68baSNigel Croxon // 269530d68baSNigel Croxon // Restore original attributes 270530d68baSNigel Croxon // 271530d68baSNigel Croxon 272530d68baSNigel Croxon if (ps.SetAttr) { 273530d68baSNigel Croxon uefi_call_wrapper(ps.SetAttr, 2, ps.Context, SavedAttribute); 274530d68baSNigel Croxon } 275530d68baSNigel Croxon 276530d68baSNigel Croxon return 0; 277530d68baSNigel Croxon } 278530d68baSNigel Croxon 279530d68baSNigel Croxon STATIC 280530d68baSNigel Croxon INTN 281530d68baSNigel Croxon IsLocalPrint(void *func) 282530d68baSNigel Croxon { 283530d68baSNigel Croxon if (func == _DbgOut || func == _SPrint || func == _PoolPrint) 284530d68baSNigel Croxon return 1; 285530d68baSNigel Croxon return 0; 286530d68baSNigel Croxon } 287530d68baSNigel Croxon 288530d68baSNigel Croxon STATIC 289530d68baSNigel Croxon INTN EFIAPI 290530d68baSNigel Croxon _DbgOut ( 291530d68baSNigel Croxon IN VOID *Context, 292530d68baSNigel Croxon IN CHAR16 *Buffer 293530d68baSNigel Croxon ) 294530d68baSNigel Croxon // Append string worker for DbgPrint 295530d68baSNigel Croxon { 296530d68baSNigel Croxon SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut; 297530d68baSNigel Croxon 298530d68baSNigel Croxon DbgOut = Context; 299530d68baSNigel Croxon // if (!DbgOut && ST && ST->ConOut) { 300530d68baSNigel Croxon // DbgOut = ST->ConOut; 301530d68baSNigel Croxon // } 302530d68baSNigel Croxon 303530d68baSNigel Croxon if (DbgOut) { 304530d68baSNigel Croxon if (IsLocalPrint(DbgOut->OutputString)) 305530d68baSNigel Croxon DbgOut->OutputString(DbgOut, Buffer); 306530d68baSNigel Croxon else 307530d68baSNigel Croxon uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer); 308530d68baSNigel Croxon } 309530d68baSNigel Croxon 310530d68baSNigel Croxon return 0; 311530d68baSNigel Croxon } 312530d68baSNigel Croxon 313530d68baSNigel Croxon INTN EFIAPI 314530d68baSNigel Croxon _SPrint ( 315530d68baSNigel Croxon IN VOID *Context, 316530d68baSNigel Croxon IN CHAR16 *Buffer 317530d68baSNigel Croxon ) 318530d68baSNigel Croxon // Append string worker for SPrint, PoolPrint and CatPrint 319530d68baSNigel Croxon { 320530d68baSNigel Croxon UINTN len; 321530d68baSNigel Croxon POOL_PRINT *spc; 322530d68baSNigel Croxon 323530d68baSNigel Croxon spc = Context; 324530d68baSNigel Croxon len = StrLen(Buffer); 325530d68baSNigel Croxon 326530d68baSNigel Croxon // 327530d68baSNigel Croxon // Is the string is over the max truncate it 328530d68baSNigel Croxon // 329530d68baSNigel Croxon 330530d68baSNigel Croxon if (spc->len + len > spc->maxlen) { 331530d68baSNigel Croxon len = spc->maxlen - spc->len; 332530d68baSNigel Croxon } 333530d68baSNigel Croxon 334530d68baSNigel Croxon // 335530d68baSNigel Croxon // Append the new text 336530d68baSNigel Croxon // 337530d68baSNigel Croxon 338530d68baSNigel Croxon CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16)); 339530d68baSNigel Croxon spc->len += len; 340530d68baSNigel Croxon 341530d68baSNigel Croxon // 342530d68baSNigel Croxon // Null terminate it 343530d68baSNigel Croxon // 344530d68baSNigel Croxon 345530d68baSNigel Croxon if (spc->len < spc->maxlen) { 346530d68baSNigel Croxon spc->str[spc->len] = 0; 347530d68baSNigel Croxon } else if (spc->maxlen) { 348dada63fdSNigel Croxon spc->str[spc->maxlen] = 0; 349530d68baSNigel Croxon } 350530d68baSNigel Croxon 351530d68baSNigel Croxon return 0; 352530d68baSNigel Croxon } 353530d68baSNigel Croxon 354530d68baSNigel Croxon 355530d68baSNigel Croxon INTN EFIAPI 356530d68baSNigel Croxon _PoolPrint ( 357530d68baSNigel Croxon IN VOID *Context, 358530d68baSNigel Croxon IN CHAR16 *Buffer 359530d68baSNigel Croxon ) 360530d68baSNigel Croxon // Append string worker for PoolPrint and CatPrint 361530d68baSNigel Croxon { 362530d68baSNigel Croxon UINTN newlen; 363530d68baSNigel Croxon POOL_PRINT *spc; 364530d68baSNigel Croxon 365530d68baSNigel Croxon spc = Context; 366530d68baSNigel Croxon newlen = spc->len + StrLen(Buffer) + 1; 367530d68baSNigel Croxon 368530d68baSNigel Croxon // 369530d68baSNigel Croxon // Is the string is over the max, grow the buffer 370530d68baSNigel Croxon // 371530d68baSNigel Croxon 372530d68baSNigel Croxon if (newlen > spc->maxlen) { 373530d68baSNigel Croxon 374530d68baSNigel Croxon // 375530d68baSNigel Croxon // Grow the pool buffer 376530d68baSNigel Croxon // 377530d68baSNigel Croxon 378530d68baSNigel Croxon newlen += PRINT_STRING_LEN; 379530d68baSNigel Croxon spc->maxlen = newlen; 380530d68baSNigel Croxon spc->str = ReallocatePool ( 381530d68baSNigel Croxon spc->str, 382530d68baSNigel Croxon spc->len * sizeof(CHAR16), 383530d68baSNigel Croxon spc->maxlen * sizeof(CHAR16) 384530d68baSNigel Croxon ); 385530d68baSNigel Croxon 386530d68baSNigel Croxon if (!spc->str) { 387530d68baSNigel Croxon spc->len = 0; 388530d68baSNigel Croxon spc->maxlen = 0; 389530d68baSNigel Croxon } 390530d68baSNigel Croxon } 391530d68baSNigel Croxon 392530d68baSNigel Croxon // 393530d68baSNigel Croxon // Append the new text 394530d68baSNigel Croxon // 395530d68baSNigel Croxon 396530d68baSNigel Croxon return _SPrint (Context, Buffer); 397530d68baSNigel Croxon } 398530d68baSNigel Croxon 399530d68baSNigel Croxon 400530d68baSNigel Croxon 401530d68baSNigel Croxon VOID 402530d68baSNigel Croxon _PoolCatPrint ( 403530d68baSNigel Croxon IN CHAR16 *fmt, 404530d68baSNigel Croxon IN va_list args, 405530d68baSNigel Croxon IN OUT POOL_PRINT *spc, 40609027207SNigel Croxon IN INTN (EFIAPI *Output)(VOID *context, CHAR16 *str) 407530d68baSNigel Croxon ) 408530d68baSNigel Croxon // Dispath function for SPrint, PoolPrint, and CatPrint 409530d68baSNigel Croxon { 410530d68baSNigel Croxon PRINT_STATE ps; 411530d68baSNigel Croxon 412530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps)); 413530d68baSNigel Croxon ps.Output = Output; 414530d68baSNigel Croxon ps.Context = spc; 415530d68baSNigel Croxon ps.fmt.pw = fmt; 416530d68baSNigel Croxon va_copy(ps.args, args); 417530d68baSNigel Croxon _Print (&ps); 418530d68baSNigel Croxon va_end(ps.args); 419530d68baSNigel Croxon } 420530d68baSNigel Croxon 421530d68baSNigel Croxon 422530d68baSNigel Croxon 423530d68baSNigel Croxon UINTN 424530d68baSNigel Croxon VSPrint ( 425530d68baSNigel Croxon OUT CHAR16 *Str, 426530d68baSNigel Croxon IN UINTN StrSize, 427530d68baSNigel Croxon IN CHAR16 *fmt, 428530d68baSNigel Croxon va_list args 429530d68baSNigel Croxon ) 430530d68baSNigel Croxon /*++ 431530d68baSNigel Croxon 432530d68baSNigel Croxon Routine Description: 433530d68baSNigel Croxon 434530d68baSNigel Croxon Prints a formatted unicode string to a buffer using a va_list 435530d68baSNigel Croxon 436530d68baSNigel Croxon Arguments: 437530d68baSNigel Croxon 438530d68baSNigel Croxon Str - Output buffer to print the formatted string into 439530d68baSNigel Croxon 440530d68baSNigel Croxon StrSize - Size of Str. String is truncated to this size. 441530d68baSNigel Croxon A size of 0 means there is no limit 442530d68baSNigel Croxon 443530d68baSNigel Croxon fmt - The format string 444530d68baSNigel Croxon 445530d68baSNigel Croxon args - va_list 446530d68baSNigel Croxon 447530d68baSNigel Croxon 448530d68baSNigel Croxon Returns: 449530d68baSNigel Croxon 450530d68baSNigel Croxon String length returned in buffer 451530d68baSNigel Croxon 452530d68baSNigel Croxon --*/ 453530d68baSNigel Croxon { 454530d68baSNigel Croxon POOL_PRINT spc; 455530d68baSNigel Croxon 456530d68baSNigel Croxon spc.str = Str; 457530d68baSNigel Croxon spc.maxlen = StrSize / sizeof(CHAR16) - 1; 458530d68baSNigel Croxon spc.len = 0; 459530d68baSNigel Croxon 460530d68baSNigel Croxon _PoolCatPrint (fmt, args, &spc, _SPrint); 461530d68baSNigel Croxon 462530d68baSNigel Croxon return spc.len; 463530d68baSNigel Croxon } 464530d68baSNigel Croxon 465530d68baSNigel Croxon UINTN 466530d68baSNigel Croxon SPrint ( 467530d68baSNigel Croxon OUT CHAR16 *Str, 468530d68baSNigel Croxon IN UINTN StrSize, 469530d68baSNigel Croxon IN CHAR16 *fmt, 470530d68baSNigel Croxon ... 471530d68baSNigel Croxon ) 472530d68baSNigel Croxon /*++ 473530d68baSNigel Croxon 474530d68baSNigel Croxon Routine Description: 475530d68baSNigel Croxon 476530d68baSNigel Croxon Prints a formatted unicode string to a buffer 477530d68baSNigel Croxon 478530d68baSNigel Croxon Arguments: 479530d68baSNigel Croxon 480530d68baSNigel Croxon Str - Output buffer to print the formatted string into 481530d68baSNigel Croxon 482530d68baSNigel Croxon StrSize - Size of Str. String is truncated to this size. 483530d68baSNigel Croxon A size of 0 means there is no limit 484530d68baSNigel Croxon 485530d68baSNigel Croxon fmt - The format string 486530d68baSNigel Croxon 487530d68baSNigel Croxon Returns: 488530d68baSNigel Croxon 489530d68baSNigel Croxon String length returned in buffer 490530d68baSNigel Croxon 491530d68baSNigel Croxon --*/ 492530d68baSNigel Croxon { 493530d68baSNigel Croxon va_list args; 494530d68baSNigel Croxon UINTN len; 495530d68baSNigel Croxon 496530d68baSNigel Croxon va_start (args, fmt); 497530d68baSNigel Croxon len = VSPrint(Str, StrSize, fmt, args); 498530d68baSNigel Croxon va_end (args); 499530d68baSNigel Croxon 500530d68baSNigel Croxon return len; 501530d68baSNigel Croxon } 502530d68baSNigel Croxon 503530d68baSNigel Croxon CHAR16 * 504530d68baSNigel Croxon VPoolPrint ( 505530d68baSNigel Croxon IN CHAR16 *fmt, 506530d68baSNigel Croxon va_list args 507530d68baSNigel Croxon ) 508530d68baSNigel Croxon /*++ 509530d68baSNigel Croxon 510530d68baSNigel Croxon Routine Description: 511530d68baSNigel Croxon 512530d68baSNigel Croxon Prints a formatted unicode string to allocated pool using va_list argument. 513530d68baSNigel Croxon The caller must free the resulting buffer. 514530d68baSNigel Croxon 515530d68baSNigel Croxon Arguments: 516530d68baSNigel Croxon 517530d68baSNigel Croxon fmt - The format string 518530d68baSNigel Croxon args - The arguments in va_list form 519530d68baSNigel Croxon 520530d68baSNigel Croxon Returns: 521530d68baSNigel Croxon 522530d68baSNigel Croxon Allocated buffer with the formatted string printed in it. 523530d68baSNigel Croxon The caller must free the allocated buffer. The buffer 524530d68baSNigel Croxon allocation is not packed. 525530d68baSNigel Croxon 526530d68baSNigel Croxon --*/ 527530d68baSNigel Croxon { 528530d68baSNigel Croxon POOL_PRINT spc; 529530d68baSNigel Croxon ZeroMem (&spc, sizeof(spc)); 530530d68baSNigel Croxon _PoolCatPrint (fmt, args, &spc, _PoolPrint); 531530d68baSNigel Croxon return spc.str; 532530d68baSNigel Croxon } 533530d68baSNigel Croxon 534530d68baSNigel Croxon CHAR16 * 535530d68baSNigel Croxon PoolPrint ( 536530d68baSNigel Croxon IN CHAR16 *fmt, 537530d68baSNigel Croxon ... 538530d68baSNigel Croxon ) 539530d68baSNigel Croxon /*++ 540530d68baSNigel Croxon 541530d68baSNigel Croxon Routine Description: 542530d68baSNigel Croxon 543530d68baSNigel Croxon Prints a formatted unicode string to allocated pool. The caller 544530d68baSNigel Croxon must free the resulting buffer. 545530d68baSNigel Croxon 546530d68baSNigel Croxon Arguments: 547530d68baSNigel Croxon 548530d68baSNigel Croxon fmt - The format string 549530d68baSNigel Croxon 550530d68baSNigel Croxon Returns: 551530d68baSNigel Croxon 552530d68baSNigel Croxon Allocated buffer with the formatted string printed in it. 553530d68baSNigel Croxon The caller must free the allocated buffer. The buffer 554530d68baSNigel Croxon allocation is not packed. 555530d68baSNigel Croxon 556530d68baSNigel Croxon --*/ 557530d68baSNigel Croxon { 558530d68baSNigel Croxon va_list args; 559530d68baSNigel Croxon CHAR16 *pool; 560530d68baSNigel Croxon va_start (args, fmt); 561530d68baSNigel Croxon pool = VPoolPrint(fmt, args); 562530d68baSNigel Croxon va_end (args); 563530d68baSNigel Croxon return pool; 564530d68baSNigel Croxon } 565530d68baSNigel Croxon 566530d68baSNigel Croxon CHAR16 * 567530d68baSNigel Croxon CatPrint ( 568530d68baSNigel Croxon IN OUT POOL_PRINT *Str, 569530d68baSNigel Croxon IN CHAR16 *fmt, 570530d68baSNigel Croxon ... 571530d68baSNigel Croxon ) 572530d68baSNigel Croxon /*++ 573530d68baSNigel Croxon 574530d68baSNigel Croxon Routine Description: 575530d68baSNigel Croxon 576530d68baSNigel Croxon Concatenates a formatted unicode string to allocated pool. 577530d68baSNigel Croxon The caller must free the resulting buffer. 578530d68baSNigel Croxon 579530d68baSNigel Croxon Arguments: 580530d68baSNigel Croxon 581530d68baSNigel Croxon Str - Tracks the allocated pool, size in use, and 582530d68baSNigel Croxon amount of pool allocated. 583530d68baSNigel Croxon 584530d68baSNigel Croxon fmt - The format string 585530d68baSNigel Croxon 586530d68baSNigel Croxon Returns: 587530d68baSNigel Croxon 588530d68baSNigel Croxon Allocated buffer with the formatted string printed in it. 589530d68baSNigel Croxon The caller must free the allocated buffer. The buffer 590530d68baSNigel Croxon allocation is not packed. 591530d68baSNigel Croxon 592530d68baSNigel Croxon --*/ 593530d68baSNigel Croxon { 594530d68baSNigel Croxon va_list args; 595530d68baSNigel Croxon 596530d68baSNigel Croxon va_start (args, fmt); 597530d68baSNigel Croxon _PoolCatPrint (fmt, args, Str, _PoolPrint); 598530d68baSNigel Croxon va_end (args); 599530d68baSNigel Croxon return Str->str; 600530d68baSNigel Croxon } 601530d68baSNigel Croxon 602530d68baSNigel Croxon 603530d68baSNigel Croxon 604530d68baSNigel Croxon UINTN 605530d68baSNigel Croxon Print ( 606530d68baSNigel Croxon IN CHAR16 *fmt, 607530d68baSNigel Croxon ... 608530d68baSNigel Croxon ) 609530d68baSNigel Croxon /*++ 610530d68baSNigel Croxon 611530d68baSNigel Croxon Routine Description: 612530d68baSNigel Croxon 613530d68baSNigel Croxon Prints a formatted unicode string to the default console 614530d68baSNigel Croxon 615530d68baSNigel Croxon Arguments: 616530d68baSNigel Croxon 617530d68baSNigel Croxon fmt - Format string 618530d68baSNigel Croxon 619530d68baSNigel Croxon Returns: 620530d68baSNigel Croxon 621530d68baSNigel Croxon Length of string printed to the console 622530d68baSNigel Croxon 623530d68baSNigel Croxon --*/ 624530d68baSNigel Croxon { 625530d68baSNigel Croxon va_list args; 626530d68baSNigel Croxon UINTN back; 627530d68baSNigel Croxon 628530d68baSNigel Croxon va_start (args, fmt); 629530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args); 630530d68baSNigel Croxon va_end (args); 631530d68baSNigel Croxon return back; 632530d68baSNigel Croxon } 633530d68baSNigel Croxon 634530d68baSNigel Croxon UINTN 635530d68baSNigel Croxon VPrint ( 636530d68baSNigel Croxon IN CHAR16 *fmt, 637530d68baSNigel Croxon va_list args 638530d68baSNigel Croxon ) 639530d68baSNigel Croxon /*++ 640530d68baSNigel Croxon 641530d68baSNigel Croxon Routine Description: 642530d68baSNigel Croxon 643530d68baSNigel Croxon Prints a formatted unicode string to the default console using a va_list 644530d68baSNigel Croxon 645530d68baSNigel Croxon Arguments: 646530d68baSNigel Croxon 647530d68baSNigel Croxon fmt - Format string 648530d68baSNigel Croxon args - va_list 649530d68baSNigel Croxon Returns: 650530d68baSNigel Croxon 651530d68baSNigel Croxon Length of string printed to the console 652530d68baSNigel Croxon 653530d68baSNigel Croxon --*/ 654530d68baSNigel Croxon { 655530d68baSNigel Croxon return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args); 656530d68baSNigel Croxon } 657530d68baSNigel Croxon 658530d68baSNigel Croxon 659530d68baSNigel Croxon UINTN 660530d68baSNigel Croxon PrintAt ( 661530d68baSNigel Croxon IN UINTN Column, 662530d68baSNigel Croxon IN UINTN Row, 663530d68baSNigel Croxon IN CHAR16 *fmt, 664530d68baSNigel Croxon ... 665530d68baSNigel Croxon ) 666530d68baSNigel Croxon /*++ 667530d68baSNigel Croxon 668530d68baSNigel Croxon Routine Description: 669530d68baSNigel Croxon 670530d68baSNigel Croxon Prints a formatted unicode string to the default console, at 671530d68baSNigel Croxon the supplied cursor position 672530d68baSNigel Croxon 673530d68baSNigel Croxon Arguments: 674530d68baSNigel Croxon 675530d68baSNigel Croxon Column, Row - The cursor position to print the string at 676530d68baSNigel Croxon 677530d68baSNigel Croxon fmt - Format string 678530d68baSNigel Croxon 679530d68baSNigel Croxon Returns: 680530d68baSNigel Croxon 681530d68baSNigel Croxon Length of string printed to the console 682530d68baSNigel Croxon 683530d68baSNigel Croxon --*/ 684530d68baSNigel Croxon { 685530d68baSNigel Croxon va_list args; 686530d68baSNigel Croxon UINTN back; 687530d68baSNigel Croxon 688530d68baSNigel Croxon va_start (args, fmt); 689530d68baSNigel Croxon back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args); 690530d68baSNigel Croxon va_end (args); 691530d68baSNigel Croxon return back; 692530d68baSNigel Croxon } 693530d68baSNigel Croxon 694530d68baSNigel Croxon 695530d68baSNigel Croxon UINTN 696530d68baSNigel Croxon IPrint ( 697530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, 698530d68baSNigel Croxon IN CHAR16 *fmt, 699530d68baSNigel Croxon ... 700530d68baSNigel Croxon ) 701530d68baSNigel Croxon /*++ 702530d68baSNigel Croxon 703530d68baSNigel Croxon Routine Description: 704530d68baSNigel Croxon 705530d68baSNigel Croxon Prints a formatted unicode string to the specified console 706530d68baSNigel Croxon 707530d68baSNigel Croxon Arguments: 708530d68baSNigel Croxon 709530d68baSNigel Croxon Out - The console to print the string too 710530d68baSNigel Croxon 711530d68baSNigel Croxon fmt - Format string 712530d68baSNigel Croxon 713530d68baSNigel Croxon Returns: 714530d68baSNigel Croxon 715530d68baSNigel Croxon Length of string printed to the console 716530d68baSNigel Croxon 717530d68baSNigel Croxon --*/ 718530d68baSNigel Croxon { 719530d68baSNigel Croxon va_list args; 720530d68baSNigel Croxon UINTN back; 721530d68baSNigel Croxon 722530d68baSNigel Croxon va_start (args, fmt); 723530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args); 724530d68baSNigel Croxon va_end (args); 725530d68baSNigel Croxon return back; 726530d68baSNigel Croxon } 727530d68baSNigel Croxon 728530d68baSNigel Croxon 729530d68baSNigel Croxon UINTN 730530d68baSNigel Croxon IPrintAt ( 731530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, 732530d68baSNigel Croxon IN UINTN Column, 733530d68baSNigel Croxon IN UINTN Row, 734530d68baSNigel Croxon IN CHAR16 *fmt, 735530d68baSNigel Croxon ... 736530d68baSNigel Croxon ) 737530d68baSNigel Croxon /*++ 738530d68baSNigel Croxon 739530d68baSNigel Croxon Routine Description: 740530d68baSNigel Croxon 741530d68baSNigel Croxon Prints a formatted unicode string to the specified console, at 742530d68baSNigel Croxon the supplied cursor position 743530d68baSNigel Croxon 744530d68baSNigel Croxon Arguments: 745530d68baSNigel Croxon 746ab6c6ef7SNigel Croxon Out - The console to print the string to 747530d68baSNigel Croxon 748530d68baSNigel Croxon Column, Row - The cursor position to print the string at 749530d68baSNigel Croxon 750530d68baSNigel Croxon fmt - Format string 751530d68baSNigel Croxon 752530d68baSNigel Croxon Returns: 753530d68baSNigel Croxon 754530d68baSNigel Croxon Length of string printed to the console 755530d68baSNigel Croxon 756530d68baSNigel Croxon --*/ 757530d68baSNigel Croxon { 758530d68baSNigel Croxon va_list args; 759530d68baSNigel Croxon UINTN back; 760530d68baSNigel Croxon 761530d68baSNigel Croxon va_start (args, fmt); 762ab6c6ef7SNigel Croxon back = _IPrint (Column, Row, Out, fmt, NULL, args); 763530d68baSNigel Croxon va_end (args); 764530d68baSNigel Croxon return back; 765530d68baSNigel Croxon } 766530d68baSNigel Croxon 767530d68baSNigel Croxon 768530d68baSNigel Croxon UINTN 769530d68baSNigel Croxon _IPrint ( 770530d68baSNigel Croxon IN UINTN Column, 771530d68baSNigel Croxon IN UINTN Row, 772530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, 773530d68baSNigel Croxon IN CHAR16 *fmt, 774530d68baSNigel Croxon IN CHAR8 *fmta, 775530d68baSNigel Croxon IN va_list args 776530d68baSNigel Croxon ) 777530d68baSNigel Croxon // Display string worker for: Print, PrintAt, IPrint, IPrintAt 778530d68baSNigel Croxon { 779530d68baSNigel Croxon PRINT_STATE ps; 780530d68baSNigel Croxon UINTN back; 781530d68baSNigel Croxon 782530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps)); 783530d68baSNigel Croxon ps.Context = Out; 78409027207SNigel Croxon ps.Output = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString; 78509027207SNigel Croxon ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) Out->SetAttribute; 786530d68baSNigel Croxon ps.Attr = Out->Mode->Attribute; 787530d68baSNigel Croxon 788530d68baSNigel Croxon back = (ps.Attr >> 4) & 0xF; 789530d68baSNigel Croxon ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back); 790530d68baSNigel Croxon ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back); 791530d68baSNigel Croxon ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back); 792530d68baSNigel Croxon 793530d68baSNigel Croxon if (fmt) { 794530d68baSNigel Croxon ps.fmt.pw = fmt; 795530d68baSNigel Croxon } else { 796530d68baSNigel Croxon ps.fmt.Ascii = TRUE; 797530d68baSNigel Croxon ps.fmt.pc = fmta; 798530d68baSNigel Croxon } 799530d68baSNigel Croxon 800530d68baSNigel Croxon va_copy(ps.args, args); 801530d68baSNigel Croxon 802530d68baSNigel Croxon if (Column != (UINTN) -1) { 803530d68baSNigel Croxon uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row); 804530d68baSNigel Croxon } 805530d68baSNigel Croxon 806530d68baSNigel Croxon back = _Print (&ps); 807530d68baSNigel Croxon va_end(ps.args); 808530d68baSNigel Croxon return back; 809530d68baSNigel Croxon } 810530d68baSNigel Croxon 811530d68baSNigel Croxon 812530d68baSNigel Croxon UINTN 813530d68baSNigel Croxon APrint ( 814530d68baSNigel Croxon IN CHAR8 *fmt, 815530d68baSNigel Croxon ... 816530d68baSNigel Croxon ) 817530d68baSNigel Croxon /*++ 818530d68baSNigel Croxon 819530d68baSNigel Croxon Routine Description: 820530d68baSNigel Croxon 821530d68baSNigel Croxon For those whom really can't deal with unicode, a print 822530d68baSNigel Croxon function that takes an ascii format string 823530d68baSNigel Croxon 824530d68baSNigel Croxon Arguments: 825530d68baSNigel Croxon 826530d68baSNigel Croxon fmt - ascii format string 827530d68baSNigel Croxon 828530d68baSNigel Croxon Returns: 829530d68baSNigel Croxon 830530d68baSNigel Croxon Length of string printed to the console 831530d68baSNigel Croxon 832530d68baSNigel Croxon --*/ 833530d68baSNigel Croxon 834530d68baSNigel Croxon { 835530d68baSNigel Croxon va_list args; 836530d68baSNigel Croxon UINTN back; 837530d68baSNigel Croxon 838530d68baSNigel Croxon va_start (args, fmt); 839530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args); 840530d68baSNigel Croxon va_end (args); 841530d68baSNigel Croxon return back; 842530d68baSNigel Croxon } 843530d68baSNigel Croxon 844530d68baSNigel Croxon 845530d68baSNigel Croxon STATIC 846530d68baSNigel Croxon VOID 847530d68baSNigel Croxon PFLUSH ( 848530d68baSNigel Croxon IN OUT PRINT_STATE *ps 849530d68baSNigel Croxon ) 850530d68baSNigel Croxon { 851530d68baSNigel Croxon *ps->Pos = 0; 852530d68baSNigel Croxon if (IsLocalPrint(ps->Output)) 853530d68baSNigel Croxon ps->Output(ps->Context, ps->Buffer); 854530d68baSNigel Croxon else 855530d68baSNigel Croxon uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer); 856530d68baSNigel Croxon ps->Pos = ps->Buffer; 857530d68baSNigel Croxon } 858530d68baSNigel Croxon 859530d68baSNigel Croxon STATIC 860530d68baSNigel Croxon VOID 861530d68baSNigel Croxon PSETATTR ( 862530d68baSNigel Croxon IN OUT PRINT_STATE *ps, 863530d68baSNigel Croxon IN UINTN Attr 864530d68baSNigel Croxon ) 865530d68baSNigel Croxon { 866530d68baSNigel Croxon PFLUSH (ps); 867530d68baSNigel Croxon 868530d68baSNigel Croxon ps->RestoreAttr = ps->Attr; 869530d68baSNigel Croxon if (ps->SetAttr) { 870530d68baSNigel Croxon uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr); 871530d68baSNigel Croxon } 872530d68baSNigel Croxon 873530d68baSNigel Croxon ps->Attr = Attr; 874530d68baSNigel Croxon } 875530d68baSNigel Croxon 876530d68baSNigel Croxon STATIC 877530d68baSNigel Croxon VOID 878530d68baSNigel Croxon PPUTC ( 879530d68baSNigel Croxon IN OUT PRINT_STATE *ps, 880530d68baSNigel Croxon IN CHAR16 c 881530d68baSNigel Croxon ) 882530d68baSNigel Croxon { 883530d68baSNigel Croxon // if this is a newline, add a carraige return 884530d68baSNigel Croxon if (c == '\n') { 885530d68baSNigel Croxon PPUTC (ps, '\r'); 886530d68baSNigel Croxon } 887530d68baSNigel Croxon 888530d68baSNigel Croxon *ps->Pos = c; 889530d68baSNigel Croxon ps->Pos += 1; 890530d68baSNigel Croxon ps->Len += 1; 891530d68baSNigel Croxon 892530d68baSNigel Croxon // if at the end of the buffer, flush it 893530d68baSNigel Croxon if (ps->Pos >= ps->End) { 894530d68baSNigel Croxon PFLUSH(ps); 895530d68baSNigel Croxon } 896530d68baSNigel Croxon } 897530d68baSNigel Croxon 898530d68baSNigel Croxon 899530d68baSNigel Croxon STATIC 900530d68baSNigel Croxon CHAR16 901530d68baSNigel Croxon PGETC ( 902530d68baSNigel Croxon IN POINTER *p 903530d68baSNigel Croxon ) 904530d68baSNigel Croxon { 905530d68baSNigel Croxon CHAR16 c; 906530d68baSNigel Croxon 907530d68baSNigel Croxon c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index]; 908530d68baSNigel Croxon p->Index += 1; 909530d68baSNigel Croxon 910530d68baSNigel Croxon return c; 911530d68baSNigel Croxon } 912530d68baSNigel Croxon 913530d68baSNigel Croxon 914530d68baSNigel Croxon STATIC 915530d68baSNigel Croxon VOID 916530d68baSNigel Croxon PITEM ( 917530d68baSNigel Croxon IN OUT PRINT_STATE *ps 918530d68baSNigel Croxon ) 919530d68baSNigel Croxon { 920530d68baSNigel Croxon UINTN Len, i; 921530d68baSNigel Croxon PRINT_ITEM *Item; 922530d68baSNigel Croxon CHAR16 c; 923530d68baSNigel Croxon 924530d68baSNigel Croxon // Get the length of the item 925530d68baSNigel Croxon Item = ps->Item; 926530d68baSNigel Croxon Item->Item.Index = 0; 927530d68baSNigel Croxon while (Item->Item.Index < Item->FieldWidth) { 928530d68baSNigel Croxon c = PGETC(&Item->Item); 929530d68baSNigel Croxon if (!c) { 930530d68baSNigel Croxon Item->Item.Index -= 1; 931530d68baSNigel Croxon break; 932530d68baSNigel Croxon } 933530d68baSNigel Croxon } 934530d68baSNigel Croxon Len = Item->Item.Index; 935530d68baSNigel Croxon 936530d68baSNigel Croxon // if there is no item field width, use the items width 937530d68baSNigel Croxon if (Item->FieldWidth == (UINTN) -1) { 938530d68baSNigel Croxon Item->FieldWidth = Len; 939530d68baSNigel Croxon } 940530d68baSNigel Croxon 941530d68baSNigel Croxon // if item is larger then width, update width 942530d68baSNigel Croxon if (Len > Item->Width) { 943530d68baSNigel Croxon Item->Width = Len; 944530d68baSNigel Croxon } 945530d68baSNigel Croxon 946530d68baSNigel Croxon 947530d68baSNigel Croxon // if pad field before, add pad char 948530d68baSNigel Croxon if (Item->PadBefore) { 949530d68baSNigel Croxon for (i=Item->Width; i < Item->FieldWidth; i+=1) { 950530d68baSNigel Croxon PPUTC (ps, ' '); 951530d68baSNigel Croxon } 952530d68baSNigel Croxon } 953530d68baSNigel Croxon 954530d68baSNigel Croxon // pad item 955530d68baSNigel Croxon for (i=Len; i < Item->Width; i++) { 956530d68baSNigel Croxon PPUTC (ps, Item->Pad); 957530d68baSNigel Croxon } 958530d68baSNigel Croxon 959530d68baSNigel Croxon // add the item 960530d68baSNigel Croxon Item->Item.Index=0; 961530d68baSNigel Croxon while (Item->Item.Index < Len) { 962530d68baSNigel Croxon PPUTC (ps, PGETC(&Item->Item)); 963530d68baSNigel Croxon } 964530d68baSNigel Croxon 965530d68baSNigel Croxon // If pad at the end, add pad char 966530d68baSNigel Croxon if (!Item->PadBefore) { 967530d68baSNigel Croxon for (i=Item->Width; i < Item->FieldWidth; i+=1) { 968530d68baSNigel Croxon PPUTC (ps, ' '); 969530d68baSNigel Croxon } 970530d68baSNigel Croxon } 971530d68baSNigel Croxon } 972530d68baSNigel Croxon 973530d68baSNigel Croxon 974530d68baSNigel Croxon STATIC 975530d68baSNigel Croxon UINTN 976530d68baSNigel Croxon _Print ( 977530d68baSNigel Croxon IN PRINT_STATE *ps 978530d68baSNigel Croxon ) 979530d68baSNigel Croxon /*++ 980530d68baSNigel Croxon 981530d68baSNigel Croxon Routine Description: 982530d68baSNigel Croxon 983530d68baSNigel Croxon %w.lF - w = width 984530d68baSNigel Croxon l = field width 985530d68baSNigel Croxon F = format of arg 986530d68baSNigel Croxon 987530d68baSNigel Croxon Args F: 988530d68baSNigel Croxon 0 - pad with zeros 989530d68baSNigel Croxon - - justify on left (default is on right) 990530d68baSNigel Croxon , - add comma's to field 991530d68baSNigel Croxon * - width provided on stack 992530d68baSNigel Croxon n - Set output attribute to normal (for this field only) 993530d68baSNigel Croxon h - Set output attribute to highlight (for this field only) 994530d68baSNigel Croxon e - Set output attribute to error (for this field only) 995530d68baSNigel Croxon l - Value is 64 bits 996530d68baSNigel Croxon 997530d68baSNigel Croxon a - ascii string 998530d68baSNigel Croxon s - unicode string 999530d68baSNigel Croxon X - fixed 8 byte value in hex 1000530d68baSNigel Croxon x - hex value 10011acb1d9dSNigel Croxon d - value as signed decimal 10021acb1d9dSNigel Croxon u - value as unsigned decimal 1003530d68baSNigel Croxon c - Unicode char 1004530d68baSNigel Croxon t - EFI time structure 1005530d68baSNigel Croxon g - Pointer to GUID 1006530d68baSNigel Croxon r - EFI status code (result code) 1007530d68baSNigel Croxon 1008530d68baSNigel Croxon N - Set output attribute to normal 1009530d68baSNigel Croxon H - Set output attribute to highlight 1010530d68baSNigel Croxon E - Set output attribute to error 1011530d68baSNigel Croxon % - Print a % 1012530d68baSNigel Croxon 1013530d68baSNigel Croxon Arguments: 1014530d68baSNigel Croxon 1015530d68baSNigel Croxon SystemTable - The system table 1016530d68baSNigel Croxon 1017530d68baSNigel Croxon Returns: 1018530d68baSNigel Croxon 1019530d68baSNigel Croxon Number of charactors written 1020530d68baSNigel Croxon 1021530d68baSNigel Croxon --*/ 1022530d68baSNigel Croxon { 1023530d68baSNigel Croxon CHAR16 c; 1024530d68baSNigel Croxon UINTN Attr; 1025530d68baSNigel Croxon PRINT_ITEM Item; 1026530d68baSNigel Croxon CHAR16 Buffer[PRINT_STRING_LEN]; 1027530d68baSNigel Croxon 1028530d68baSNigel Croxon ps->Len = 0; 1029530d68baSNigel Croxon ps->Buffer = Buffer; 1030530d68baSNigel Croxon ps->Pos = Buffer; 1031530d68baSNigel Croxon ps->End = Buffer + PRINT_STRING_LEN - 1; 1032530d68baSNigel Croxon ps->Item = &Item; 1033530d68baSNigel Croxon 1034530d68baSNigel Croxon ps->fmt.Index = 0; 1035530d68baSNigel Croxon while ((c = PGETC(&ps->fmt))) { 1036530d68baSNigel Croxon 1037530d68baSNigel Croxon if (c != '%') { 1038530d68baSNigel Croxon PPUTC ( ps, c ); 1039530d68baSNigel Croxon continue; 1040530d68baSNigel Croxon } 1041530d68baSNigel Croxon 1042530d68baSNigel Croxon // setup for new item 1043530d68baSNigel Croxon Item.FieldWidth = (UINTN) -1; 1044530d68baSNigel Croxon Item.Width = 0; 1045530d68baSNigel Croxon Item.WidthParse = &Item.Width; 1046530d68baSNigel Croxon Item.Pad = ' '; 1047530d68baSNigel Croxon Item.PadBefore = TRUE; 1048530d68baSNigel Croxon Item.Comma = FALSE; 1049530d68baSNigel Croxon Item.Long = FALSE; 1050530d68baSNigel Croxon Item.Item.Ascii = FALSE; 1051530d68baSNigel Croxon Item.Item.pw = NULL; 1052530d68baSNigel Croxon ps->RestoreAttr = 0; 1053530d68baSNigel Croxon Attr = 0; 1054530d68baSNigel Croxon 1055530d68baSNigel Croxon while ((c = PGETC(&ps->fmt))) { 1056530d68baSNigel Croxon 1057530d68baSNigel Croxon switch (c) { 1058530d68baSNigel Croxon 1059530d68baSNigel Croxon case '%': 1060530d68baSNigel Croxon // 1061530d68baSNigel Croxon // %% -> % 1062530d68baSNigel Croxon // 1063530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1064530d68baSNigel Croxon Item.Item.pw[0] = '%'; 1065530d68baSNigel Croxon Item.Item.pw[1] = 0; 1066530d68baSNigel Croxon break; 1067530d68baSNigel Croxon 1068530d68baSNigel Croxon case '0': 1069530d68baSNigel Croxon Item.Pad = '0'; 1070530d68baSNigel Croxon break; 1071530d68baSNigel Croxon 1072530d68baSNigel Croxon case '-': 1073530d68baSNigel Croxon Item.PadBefore = FALSE; 1074530d68baSNigel Croxon break; 1075530d68baSNigel Croxon 1076530d68baSNigel Croxon case ',': 1077530d68baSNigel Croxon Item.Comma = TRUE; 1078530d68baSNigel Croxon break; 1079530d68baSNigel Croxon 1080530d68baSNigel Croxon case '.': 1081530d68baSNigel Croxon Item.WidthParse = &Item.FieldWidth; 1082530d68baSNigel Croxon break; 1083530d68baSNigel Croxon 1084530d68baSNigel Croxon case '*': 1085530d68baSNigel Croxon *Item.WidthParse = va_arg(ps->args, UINTN); 1086530d68baSNigel Croxon break; 1087530d68baSNigel Croxon 1088530d68baSNigel Croxon case '1': 1089530d68baSNigel Croxon case '2': 1090530d68baSNigel Croxon case '3': 1091530d68baSNigel Croxon case '4': 1092530d68baSNigel Croxon case '5': 1093530d68baSNigel Croxon case '6': 1094530d68baSNigel Croxon case '7': 1095530d68baSNigel Croxon case '8': 1096530d68baSNigel Croxon case '9': 1097530d68baSNigel Croxon *Item.WidthParse = 0; 1098530d68baSNigel Croxon do { 1099530d68baSNigel Croxon *Item.WidthParse = *Item.WidthParse * 10 + c - '0'; 1100530d68baSNigel Croxon c = PGETC(&ps->fmt); 1101530d68baSNigel Croxon } while (c >= '0' && c <= '9') ; 1102530d68baSNigel Croxon ps->fmt.Index -= 1; 1103530d68baSNigel Croxon break; 1104530d68baSNigel Croxon 1105530d68baSNigel Croxon case 'a': 1106530d68baSNigel Croxon Item.Item.pc = va_arg(ps->args, CHAR8 *); 1107530d68baSNigel Croxon Item.Item.Ascii = TRUE; 1108530d68baSNigel Croxon if (!Item.Item.pc) { 1109530d68baSNigel Croxon Item.Item.pc = (CHAR8 *)"(null)"; 1110530d68baSNigel Croxon } 1111530d68baSNigel Croxon break; 1112530d68baSNigel Croxon 1113530d68baSNigel Croxon case 's': 1114530d68baSNigel Croxon Item.Item.pw = va_arg(ps->args, CHAR16 *); 1115530d68baSNigel Croxon if (!Item.Item.pw) { 1116530d68baSNigel Croxon Item.Item.pw = L"(null)"; 1117530d68baSNigel Croxon } 1118530d68baSNigel Croxon break; 1119530d68baSNigel Croxon 1120530d68baSNigel Croxon case 'c': 1121530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1122530d68baSNigel Croxon Item.Item.pw[0] = (CHAR16) va_arg(ps->args, UINTN); 1123530d68baSNigel Croxon Item.Item.pw[1] = 0; 1124530d68baSNigel Croxon break; 1125530d68baSNigel Croxon 1126530d68baSNigel Croxon case 'l': 1127530d68baSNigel Croxon Item.Long = TRUE; 1128530d68baSNigel Croxon break; 1129530d68baSNigel Croxon 1130530d68baSNigel Croxon case 'X': 1131530d68baSNigel Croxon Item.Width = Item.Long ? 16 : 8; 1132530d68baSNigel Croxon Item.Pad = '0'; 1133530d68baSNigel Croxon case 'x': 1134530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1135530d68baSNigel Croxon ValueToHex ( 1136530d68baSNigel Croxon Item.Item.pw, 1137530d68baSNigel Croxon Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) 1138530d68baSNigel Croxon ); 1139530d68baSNigel Croxon 1140530d68baSNigel Croxon break; 1141530d68baSNigel Croxon 1142530d68baSNigel Croxon 1143530d68baSNigel Croxon case 'g': 1144530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1145530d68baSNigel Croxon GuidToString (Item.Item.pw, va_arg(ps->args, EFI_GUID *)); 1146530d68baSNigel Croxon break; 1147530d68baSNigel Croxon 11481acb1d9dSNigel Croxon case 'u': 1149530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1150530d68baSNigel Croxon ValueToString ( 1151530d68baSNigel Croxon Item.Item.pw, 1152530d68baSNigel Croxon Item.Comma, 1153530d68baSNigel Croxon Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) 1154530d68baSNigel Croxon ); 11551acb1d9dSNigel Croxon break; 11561acb1d9dSNigel Croxon 11571acb1d9dSNigel Croxon case 'd': 11581acb1d9dSNigel Croxon Item.Item.pw = Item.Scratch; 11591acb1d9dSNigel Croxon ValueToString ( 11601acb1d9dSNigel Croxon Item.Item.pw, 11611acb1d9dSNigel Croxon Item.Comma, 11621acb1d9dSNigel Croxon Item.Long ? va_arg(ps->args, INT64) : va_arg(ps->args, INT32) 11631acb1d9dSNigel Croxon ); 11641acb1d9dSNigel Croxon break; 11651acb1d9dSNigel Croxon 1166530d68baSNigel Croxon case 't': 1167530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1168530d68baSNigel Croxon TimeToString (Item.Item.pw, va_arg(ps->args, EFI_TIME *)); 1169530d68baSNigel Croxon break; 1170530d68baSNigel Croxon 1171530d68baSNigel Croxon case 'r': 1172530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1173530d68baSNigel Croxon StatusToString (Item.Item.pw, va_arg(ps->args, EFI_STATUS)); 1174530d68baSNigel Croxon break; 1175530d68baSNigel Croxon 1176530d68baSNigel Croxon case 'n': 1177530d68baSNigel Croxon PSETATTR(ps, ps->AttrNorm); 1178530d68baSNigel Croxon break; 1179530d68baSNigel Croxon 1180530d68baSNigel Croxon case 'h': 1181530d68baSNigel Croxon PSETATTR(ps, ps->AttrHighlight); 1182530d68baSNigel Croxon break; 1183530d68baSNigel Croxon 1184530d68baSNigel Croxon case 'e': 1185530d68baSNigel Croxon PSETATTR(ps, ps->AttrError); 1186530d68baSNigel Croxon break; 1187530d68baSNigel Croxon 1188530d68baSNigel Croxon case 'N': 1189530d68baSNigel Croxon Attr = ps->AttrNorm; 1190530d68baSNigel Croxon break; 1191530d68baSNigel Croxon 1192530d68baSNigel Croxon case 'H': 1193530d68baSNigel Croxon Attr = ps->AttrHighlight; 1194530d68baSNigel Croxon break; 1195530d68baSNigel Croxon 1196530d68baSNigel Croxon case 'E': 1197530d68baSNigel Croxon Attr = ps->AttrError; 1198530d68baSNigel Croxon break; 1199530d68baSNigel Croxon 1200530d68baSNigel Croxon default: 1201530d68baSNigel Croxon Item.Item.pw = Item.Scratch; 1202530d68baSNigel Croxon Item.Item.pw[0] = '?'; 1203530d68baSNigel Croxon Item.Item.pw[1] = 0; 1204530d68baSNigel Croxon break; 1205530d68baSNigel Croxon } 1206530d68baSNigel Croxon 1207530d68baSNigel Croxon // if we have an Item 1208530d68baSNigel Croxon if (Item.Item.pw) { 1209530d68baSNigel Croxon PITEM (ps); 1210530d68baSNigel Croxon break; 1211530d68baSNigel Croxon } 1212530d68baSNigel Croxon 1213530d68baSNigel Croxon // if we have an Attr set 1214530d68baSNigel Croxon if (Attr) { 1215530d68baSNigel Croxon PSETATTR(ps, Attr); 1216530d68baSNigel Croxon ps->RestoreAttr = 0; 1217530d68baSNigel Croxon break; 1218530d68baSNigel Croxon } 1219530d68baSNigel Croxon } 1220530d68baSNigel Croxon 1221530d68baSNigel Croxon if (ps->RestoreAttr) { 1222530d68baSNigel Croxon PSETATTR(ps, ps->RestoreAttr); 1223530d68baSNigel Croxon } 1224530d68baSNigel Croxon } 1225530d68baSNigel Croxon 1226530d68baSNigel Croxon // Flush buffer 1227530d68baSNigel Croxon PFLUSH (ps); 1228530d68baSNigel Croxon return ps->Len; 1229530d68baSNigel Croxon } 1230530d68baSNigel Croxon 1231530d68baSNigel Croxon STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7', 1232530d68baSNigel Croxon '8','9','A','B','C','D','E','F'}; 1233530d68baSNigel Croxon 1234530d68baSNigel Croxon VOID 1235530d68baSNigel Croxon ValueToHex ( 1236530d68baSNigel Croxon IN CHAR16 *Buffer, 1237530d68baSNigel Croxon IN UINT64 v 1238530d68baSNigel Croxon ) 1239530d68baSNigel Croxon { 1240530d68baSNigel Croxon CHAR8 str[30], *p1; 1241530d68baSNigel Croxon CHAR16 *p2; 1242530d68baSNigel Croxon 1243530d68baSNigel Croxon if (!v) { 1244530d68baSNigel Croxon Buffer[0] = '0'; 1245530d68baSNigel Croxon Buffer[1] = 0; 1246530d68baSNigel Croxon return ; 1247530d68baSNigel Croxon } 1248530d68baSNigel Croxon 1249530d68baSNigel Croxon p1 = str; 1250530d68baSNigel Croxon p2 = Buffer; 1251530d68baSNigel Croxon 1252530d68baSNigel Croxon while (v) { 1253*38c57d52SNigel Croxon // Without the cast, the MSVC compiler may insert a reference to __allmull 1254*38c57d52SNigel Croxon *(p1++) = Hex[(UINTN)(v & 0xf)]; 1255530d68baSNigel Croxon v = RShiftU64 (v, 4); 1256530d68baSNigel Croxon } 1257530d68baSNigel Croxon 1258530d68baSNigel Croxon while (p1 != str) { 1259530d68baSNigel Croxon *(p2++) = *(--p1); 1260530d68baSNigel Croxon } 1261530d68baSNigel Croxon *p2 = 0; 1262530d68baSNigel Croxon } 1263530d68baSNigel Croxon 1264530d68baSNigel Croxon 1265530d68baSNigel Croxon VOID 1266530d68baSNigel Croxon ValueToString ( 1267530d68baSNigel Croxon IN CHAR16 *Buffer, 1268530d68baSNigel Croxon IN BOOLEAN Comma, 1269530d68baSNigel Croxon IN INT64 v 1270530d68baSNigel Croxon ) 1271530d68baSNigel Croxon { 1272530d68baSNigel Croxon STATIC CHAR8 ca[] = { 3, 1, 2 }; 1273530d68baSNigel Croxon CHAR8 str[40], *p1; 1274530d68baSNigel Croxon CHAR16 *p2; 1275530d68baSNigel Croxon UINTN c, r; 1276530d68baSNigel Croxon 1277530d68baSNigel Croxon if (!v) { 1278530d68baSNigel Croxon Buffer[0] = '0'; 1279530d68baSNigel Croxon Buffer[1] = 0; 1280530d68baSNigel Croxon return ; 1281530d68baSNigel Croxon } 1282530d68baSNigel Croxon 1283530d68baSNigel Croxon p1 = str; 1284530d68baSNigel Croxon p2 = Buffer; 1285530d68baSNigel Croxon 1286530d68baSNigel Croxon if (v < 0) { 1287530d68baSNigel Croxon *(p2++) = '-'; 1288530d68baSNigel Croxon v = -v; 1289530d68baSNigel Croxon } 1290530d68baSNigel Croxon 1291530d68baSNigel Croxon while (v) { 1292530d68baSNigel Croxon v = (INT64)DivU64x32 ((UINT64)v, 10, &r); 1293530d68baSNigel Croxon *(p1++) = (CHAR8)r + '0'; 1294530d68baSNigel Croxon } 1295530d68baSNigel Croxon 1296530d68baSNigel Croxon c = (Comma ? ca[(p1 - str) % 3] : 999) + 1; 1297530d68baSNigel Croxon while (p1 != str) { 1298530d68baSNigel Croxon 1299530d68baSNigel Croxon c -= 1; 1300530d68baSNigel Croxon if (!c) { 1301530d68baSNigel Croxon *(p2++) = ','; 1302530d68baSNigel Croxon c = 3; 1303530d68baSNigel Croxon } 1304530d68baSNigel Croxon 1305530d68baSNigel Croxon *(p2++) = *(--p1); 1306530d68baSNigel Croxon } 1307530d68baSNigel Croxon *p2 = 0; 1308530d68baSNigel Croxon } 1309530d68baSNigel Croxon 1310530d68baSNigel Croxon VOID 1311530d68baSNigel Croxon TimeToString ( 1312530d68baSNigel Croxon OUT CHAR16 *Buffer, 1313530d68baSNigel Croxon IN EFI_TIME *Time 1314530d68baSNigel Croxon ) 1315530d68baSNigel Croxon { 1316530d68baSNigel Croxon UINTN Hour, Year; 1317530d68baSNigel Croxon CHAR16 AmPm; 1318530d68baSNigel Croxon 1319530d68baSNigel Croxon AmPm = 'a'; 1320530d68baSNigel Croxon Hour = Time->Hour; 1321530d68baSNigel Croxon if (Time->Hour == 0) { 1322530d68baSNigel Croxon Hour = 12; 1323530d68baSNigel Croxon } else if (Time->Hour >= 12) { 1324530d68baSNigel Croxon AmPm = 'p'; 1325530d68baSNigel Croxon if (Time->Hour >= 13) { 1326530d68baSNigel Croxon Hour -= 12; 1327530d68baSNigel Croxon } 1328530d68baSNigel Croxon } 1329530d68baSNigel Croxon 1330530d68baSNigel Croxon Year = Time->Year % 100; 1331530d68baSNigel Croxon 1332530d68baSNigel Croxon // bugbug: for now just print it any old way 1333530d68baSNigel Croxon SPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c", 1334530d68baSNigel Croxon Time->Month, 1335530d68baSNigel Croxon Time->Day, 1336530d68baSNigel Croxon Year, 1337530d68baSNigel Croxon Hour, 1338530d68baSNigel Croxon Time->Minute, 1339530d68baSNigel Croxon AmPm 1340530d68baSNigel Croxon ); 1341530d68baSNigel Croxon } 1342530d68baSNigel Croxon 1343530d68baSNigel Croxon 1344530d68baSNigel Croxon 1345530d68baSNigel Croxon 1346530d68baSNigel Croxon VOID 1347530d68baSNigel Croxon DumpHex ( 1348530d68baSNigel Croxon IN UINTN Indent, 1349530d68baSNigel Croxon IN UINTN Offset, 1350530d68baSNigel Croxon IN UINTN DataSize, 1351530d68baSNigel Croxon IN VOID *UserData 1352530d68baSNigel Croxon ) 1353530d68baSNigel Croxon { 1354530d68baSNigel Croxon CHAR8 *Data, Val[50], Str[20], c; 1355530d68baSNigel Croxon UINTN Size, Index; 1356530d68baSNigel Croxon 1357530d68baSNigel Croxon UINTN ScreenCount; 1358530d68baSNigel Croxon UINTN TempColumn; 1359530d68baSNigel Croxon UINTN ScreenSize; 1360530d68baSNigel Croxon CHAR16 ReturnStr[1]; 1361530d68baSNigel Croxon 1362530d68baSNigel Croxon 1363530d68baSNigel Croxon uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize); 1364530d68baSNigel Croxon ScreenCount = 0; 1365530d68baSNigel Croxon ScreenSize -= 2; 1366530d68baSNigel Croxon 1367530d68baSNigel Croxon Data = UserData; 1368530d68baSNigel Croxon while (DataSize) { 1369530d68baSNigel Croxon Size = 16; 1370530d68baSNigel Croxon if (Size > DataSize) { 1371530d68baSNigel Croxon Size = DataSize; 1372530d68baSNigel Croxon } 1373530d68baSNigel Croxon 1374530d68baSNigel Croxon for (Index=0; Index < Size; Index += 1) { 1375530d68baSNigel Croxon c = Data[Index]; 1376530d68baSNigel Croxon Val[Index*3+0] = Hex[c>>4]; 1377530d68baSNigel Croxon Val[Index*3+1] = Hex[c&0xF]; 1378530d68baSNigel Croxon Val[Index*3+2] = (Index == 7)?'-':' '; 1379530d68baSNigel Croxon Str[Index] = (c < ' ' || c > 'z') ? '.' : c; 1380530d68baSNigel Croxon } 1381530d68baSNigel Croxon 1382530d68baSNigel Croxon Val[Index*3] = 0; 1383530d68baSNigel Croxon Str[Index] = 0; 1384530d68baSNigel Croxon Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str); 1385530d68baSNigel Croxon 1386530d68baSNigel Croxon Data += Size; 1387530d68baSNigel Croxon Offset += Size; 1388530d68baSNigel Croxon DataSize -= Size; 1389530d68baSNigel Croxon 1390530d68baSNigel Croxon ScreenCount++; 1391530d68baSNigel Croxon if (ScreenCount >= ScreenSize && ScreenSize != 0) { 1392530d68baSNigel Croxon // 1393530d68baSNigel Croxon // If ScreenSize == 0 we have the console redirected so don't 1394530d68baSNigel Croxon // block updates 1395530d68baSNigel Croxon // 1396530d68baSNigel Croxon ScreenCount = 0; 1397530d68baSNigel Croxon Print (L"Press Enter to continue :"); 1398530d68baSNigel Croxon Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16)); 1399530d68baSNigel Croxon Print (L"\n"); 1400530d68baSNigel Croxon } 1401530d68baSNigel Croxon 1402530d68baSNigel Croxon } 1403530d68baSNigel Croxon } 1404