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