]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Print.c
2ed4eeca23d95c338d0046f207e7186c46360aa4
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Print.c
15
16 Abstract:
17
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
20
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
23
24 VSPrint, Print, SPrint format specification has the follwoing form
25
26 %[flags][width]type
27
28 flags:
29 '-' - Left justify
30 '+' - Prefix a sign
31 ' ' - Prefix a blank
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
34 'l' - UINT64
35 'L' - UINT64
36
37 width:
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
40
41 type:
42 'X' - argument is a UINTN hex number, prefix '0'
43 'x' - argument is a hex number
44 'd' - argument is a decimal number
45 'a' - argument is an ascii string
46 'S','s' - argument is an Unicode string
47 'g' - argument is a pointer to an EFI_GUID
48 't' - argument is a pointer to an EFI_TIME structure
49 'c' - argument is an ascii character
50 'r' - argument is EFI_STATUS
51 '%' - Print a %
52
53 --*/
54
55 #include "Tiano.h"
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
61 #include "Print.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
64 #else
65 #include EFI_PROTOCOL_DEFINITION (Hii)
66 #endif
67
68 STATIC
69 CHAR_W *
70 GetFlagsAndWidth (
71 IN CHAR_W *Format,
72 OUT UINTN *Flags,
73 OUT UINTN *Width,
74 IN OUT VA_LIST *Marker
75 );
76
77 STATIC
78 UINTN
79 GuidToString (
80 IN EFI_GUID *Guid,
81 IN OUT CHAR_W *Buffer,
82 IN UINTN BufferSize
83 );
84
85 STATIC
86 UINTN
87 TimeToString (
88 IN EFI_TIME *Time,
89 IN OUT CHAR_W *Buffer,
90 IN UINTN BufferSize
91 );
92
93 STATIC
94 UINTN
95 EfiStatusToString (
96 IN EFI_STATUS Status,
97 OUT CHAR_W *Buffer,
98 IN UINTN BufferSize
99 );
100
101 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {
102 {0x00, 0x00, 0x00, 0x00},
103 {0x98, 0x00, 0x00, 0x00},
104 {0x00, 0x98, 0x00, 0x00},
105 {0x98, 0x98, 0x00, 0x00},
106 {0x00, 0x00, 0x98, 0x00},
107 {0x98, 0x00, 0x98, 0x00},
108 {0x00, 0x98, 0x98, 0x00},
109 {0x98, 0x98, 0x98, 0x00},
110 {0x10, 0x10, 0x10, 0x00},
111 {0xff, 0x10, 0x10, 0x00},
112 {0x10, 0xff, 0x10, 0x00},
113 {0xff, 0xff, 0x10, 0x00},
114 {0x10, 0x10, 0xff, 0x00},
115 {0xf0, 0x10, 0xff, 0x00},
116 {0x10, 0xff, 0xff, 0x00},
117 {0xff, 0xff, 0xff, 0x00},
118 };
119
120
121 UINTN
122 _IPrint (
123 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
124 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
125 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,
126 IN UINTN X,
127 IN UINTN Y,
128 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
129 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,
130 IN CHAR16 *fmt,
131 IN VA_LIST args
132 )
133 /*++
134
135 Routine Description:
136
137 Display string worker for: Print, PrintAt, IPrint, IPrintAt
138
139 Arguments:
140
141 GraphicsOutput - Graphics output protocol interface
142
143 UgaDraw - UGA draw protocol interface
144
145 Sto - Simple text out protocol interface
146
147 X - X coordinate to start printing
148
149 Y - Y coordinate to start printing
150
151 Foreground - Foreground color
152
153 Background - Background color
154
155 fmt - Format string
156
157 args - Print arguments
158
159 Returns:
160
161 EFI_SUCCESS - success
162 EFI_OUT_OF_RESOURCES - out of resources
163
164 --*/
165 {
166 VOID *Buffer;
167 EFI_STATUS Status;
168 UINTN Index;
169 CHAR16 *UnicodeWeight;
170 UINT32 HorizontalResolution;
171 UINT32 VerticalResolution;
172 UINT32 ColorDepth;
173 UINT32 RefreshRate;
174 UINTN BufferLen;
175 UINTN LineBufferLen;
176 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
177 EFI_HII_FONT_PROTOCOL *HiiFont;
178 EFI_IMAGE_OUTPUT *Blt;
179 EFI_FONT_DISPLAY_INFO *FontInfo;
180 #else
181 EFI_HII_PROTOCOL *Hii;
182 UINT16 GlyphWidth;
183 UINT32 GlyphStatus;
184 UINT16 StringIndex;
185 EFI_NARROW_GLYPH *Glyph;
186 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
187 #endif
188
189 //
190 // For now, allocate an arbitrarily long buffer
191 //
192 Buffer = EfiLibAllocateZeroPool (0x10000);
193 if (Buffer == NULL) {
194 return EFI_OUT_OF_RESOURCES;
195 }
196
197 if (GraphicsOutput != NULL) {
198 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
199 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
200 } else {
201 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
202 }
203 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));
204
205 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
206 Blt = NULL;
207 FontInfo = NULL;
208 ASSERT (GraphicsOutput != NULL);
209 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);
210 if (EFI_ERROR (Status)) {
211 goto Error;
212 }
213 #else
214 LineBuffer = NULL;
215 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID**)&Hii);
216 if (EFI_ERROR (Status)) {
217 goto Error;
218 }
219 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;
220 LineBuffer = EfiLibAllocatePool (LineBufferLen);
221 if (LineBuffer == NULL) {
222 Status = EFI_OUT_OF_RESOURCES;
223 goto Error;
224 }
225 #endif
226
227 VSPrint (Buffer, 0x10000, fmt, args);
228
229 UnicodeWeight = (CHAR16 *) Buffer;
230
231 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {
232 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||
233 UnicodeWeight[Index] == CHAR_LINEFEED ||
234 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {
235 UnicodeWeight[Index] = 0;
236 }
237 }
238
239 BufferLen = EfiStrLen (Buffer);
240
241
242 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
243 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;
244 if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
245 Status = EFI_INVALID_PARAMETER;
246 goto Error;
247 }
248
249 Blt = (EFI_IMAGE_OUTPUT *) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
250 if (Blt == NULL) {
251 Status = EFI_OUT_OF_RESOURCES;
252 goto Error;
253 }
254
255 Blt->Width = (UINT16) (HorizontalResolution);
256 Blt->Height = (UINT16) (VerticalResolution);
257 Blt->Image.Screen = GraphicsOutput;
258
259 FontInfo = (EFI_FONT_DISPLAY_INFO *) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
260 if (FontInfo == NULL) {
261 Status = EFI_OUT_OF_RESOURCES;
262 goto Error;
263 }
264 if (Foreground != NULL) {
265 EfiCopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
266 } else {
267 EfiCopyMem (
268 &FontInfo->ForegroundColor,
269 &mEfiColors[Sto->Mode->Attribute & 0x0f],
270 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
271 );
272 }
273 if (Background != NULL) {
274 EfiCopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
275 } else {
276 EfiCopyMem (
277 &FontInfo->BackgroundColor,
278 &mEfiColors[Sto->Mode->Attribute >> 4],
279 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
280 );
281 }
282
283 Status = HiiFont->StringToImage (
284 HiiFont,
285 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,
286 Buffer,
287 FontInfo,
288 &Blt,
289 X,
290 Y,
291 NULL,
292 NULL,
293 NULL
294 );
295
296 #else
297 GlyphStatus = 0;
298
299 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
300 Status = EFI_INVALID_PARAMETER;
301 goto Error;
302 }
303
304 for (Index = 0; Index < BufferLen; Index++) {
305 StringIndex = (UINT16) Index;
306 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);
307 if (EFI_ERROR (Status)) {
308 goto Error;
309 }
310
311 if (Foreground == NULL || Background == NULL) {
312 Status = Hii->GlyphToBlt (
313 Hii,
314 (UINT8 *) Glyph,
315 mEfiColors[Sto->Mode->Attribute & 0x0f],
316 mEfiColors[Sto->Mode->Attribute >> 4],
317 BufferLen,
318 GlyphWidth,
319 GLYPH_HEIGHT,
320 &LineBuffer[Index * GLYPH_WIDTH]
321 );
322 } else {
323 Status = Hii->GlyphToBlt (
324 Hii,
325 (UINT8 *) Glyph,
326 *Foreground,
327 *Background,
328 BufferLen,
329 GlyphWidth,
330 GLYPH_HEIGHT,
331 &LineBuffer[Index * GLYPH_WIDTH]
332 );
333 }
334 }
335
336 //
337 // Blt a character to the screen
338 //
339 if (GraphicsOutput != NULL) {
340 Status = GraphicsOutput->Blt (
341 GraphicsOutput,
342 LineBuffer,
343 EfiBltBufferToVideo,
344 0,
345 0,
346 X,
347 Y,
348 GLYPH_WIDTH * BufferLen,
349 GLYPH_HEIGHT,
350 GLYPH_WIDTH * BufferLen * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
351 );
352 } else {
353 Status = UgaDraw->Blt (
354 UgaDraw,
355 (EFI_UGA_PIXEL *) LineBuffer,
356 EfiUgaBltBufferToVideo,
357 0,
358 0,
359 X,
360 Y,
361 GLYPH_WIDTH * BufferLen,
362 GLYPH_HEIGHT,
363 GLYPH_WIDTH * BufferLen * sizeof (EFI_UGA_PIXEL)
364 );
365 }
366
367 #endif
368
369 Error:
370 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
371 EfiLibSafeFreePool (Blt);
372 EfiLibSafeFreePool (FontInfo);
373 #else
374 gBS->FreePool (LineBuffer);
375 #endif
376 gBS->FreePool (Buffer);
377 return Status;
378 }
379
380
381 UINTN
382 PrintXY (
383 IN UINTN X,
384 IN UINTN Y,
385 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
386 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
387 IN CHAR_W *Fmt,
388 ...
389 )
390 /*++
391
392 Routine Description:
393
394 Prints a formatted unicode string to the default console
395
396 Arguments:
397
398 X - X coordinate to start printing
399
400 Y - Y coordinate to start printing
401
402 ForeGround - Foreground color
403
404 BackGround - Background color
405
406 Fmt - Format string
407
408 ... - Print arguments
409
410 Returns:
411
412 Length of string printed to the console
413
414 --*/
415 {
416 EFI_HANDLE Handle;
417 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
418 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
419 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
420 EFI_STATUS Status;
421 VA_LIST Args;
422
423 VA_START (Args, Fmt);
424
425 Handle = gST->ConsoleOutHandle;
426
427 Status = gBS->HandleProtocol (
428 Handle,
429 &gEfiGraphicsOutputProtocolGuid,
430 (VOID**)&GraphicsOutput
431 );
432
433 UgaDraw = NULL;
434 if (EFI_ERROR (Status)) {
435 GraphicsOutput = NULL;
436
437 Status = gBS->HandleProtocol (
438 Handle,
439 &gEfiUgaDrawProtocolGuid,
440 (VOID**)&UgaDraw
441 );
442
443 if (EFI_ERROR (Status)) {
444 return Status;
445 }
446 }
447
448 Status = gBS->HandleProtocol (
449 Handle,
450 &gEfiSimpleTextOutProtocolGuid,
451 (VOID**)&Sto
452 );
453
454 if (EFI_ERROR (Status)) {
455 return Status;
456 }
457
458 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
459 }
460
461
462 UINTN
463 SPrint (
464 OUT CHAR_W *Buffer,
465 IN UINTN BufferSize,
466 IN CONST CHAR_W *Format,
467 ...
468 )
469 /*++
470
471 Routine Description:
472
473 SPrint function to process format and place the results in Buffer.
474
475 Arguments:
476
477 Buffer - Wide char buffer to print the results of the parsing of Format into.
478
479 BufferSize - Maximum number of characters to put into buffer. Zero means no
480 limit.
481
482 Format - Format string see file header for more details.
483
484 ... - Vararg list consumed by processing Format.
485
486 Returns:
487
488 Number of characters printed.
489
490 --*/
491 {
492 UINTN Return;
493 VA_LIST Marker;
494
495 VA_START (Marker, Format);
496 Return = VSPrint (Buffer, BufferSize, Format, Marker);
497 VA_END (Marker);
498
499 return Return;
500 }
501
502 UINTN
503 EFIAPI
504 VSPrint (
505 OUT CHAR_W *StartOfBuffer,
506 IN UINTN BufferSize,
507 IN CONST CHAR_W *FormatString,
508 IN VA_LIST Marker
509 )
510 /*++
511
512 Routine Description:
513
514 VSPrint function to process format and place the results in Buffer. Since a
515 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
516 this is the main print working routine
517
518 Arguments:
519
520 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
521
522 BufferSize - Maximum number of characters to put into buffer. Zero means
523 no limit.
524
525 FormatString - Unicode format string see file header for more details.
526
527 Marker - Vararg list consumed by processing Format.
528
529 Returns:
530
531 Number of characters printed.
532
533 --*/
534 {
535 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
536 CHAR_W *Buffer;
537 CHAR8 *AsciiStr;
538 CHAR16 *UnicodeStr;
539 CHAR_W *Format;
540 UINTN Index;
541 UINTN Flags;
542 UINTN Width;
543 UINTN Count;
544 UINTN NumberOfCharacters;
545 UINTN BufferLeft;
546 UINT64 Value;
547 EFI_GUID *TmpGUID;
548
549 //
550 // Process the format string. Stop if Buffer is over run.
551 //
552
553 Buffer = StartOfBuffer;
554 Format = (CHAR_W *) FormatString;
555 NumberOfCharacters = BufferSize / sizeof (CHAR_W);
556 BufferLeft = BufferSize;
557 for (Index = 0; (*Format != '\0') && (Index < NumberOfCharacters - 1); Format++) {
558 if (*Format != '%') {
559 if ((*Format == '\n') && (Index < NumberOfCharacters - 2)) {
560 //
561 // If carage return add line feed
562 //
563 Buffer[Index++] = '\r';
564 BufferLeft -= sizeof (CHAR_W);
565 }
566
567 Buffer[Index++] = *Format;
568 BufferLeft -= sizeof (CHAR_W);
569 } else {
570
571 //
572 // Now it's time to parse what follows after %
573 //
574 Format = GetFlagsAndWidth (Format, &Flags, &Width, &Marker);
575 switch (*Format) {
576 case 'p':
577 //
578 // Flag space, +, 0, L & l are invalid for type p.
579 //
580 Flags &= ~(PREFIX_BLANK| PREFIX_SIGN | LONG_TYPE);
581 if (sizeof (VOID *) > 4) {
582 Flags |= LONG_TYPE;
583 Value = VA_ARG (Marker, UINT64);
584 } else {
585 Value = VA_ARG (Marker, UINTN);
586 }
587 Flags |= PREFIX_ZERO;
588
589 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
590 UnicodeStr = TempBuffer;
591
592 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
593 Buffer[Index++] = *UnicodeStr;
594 }
595 break;
596
597 case 'X':
598 Flags |= PREFIX_ZERO;
599 Width = sizeof (UINT64) * 2;
600
601 //
602 // break skiped on purpose
603 //
604 case 'x':
605 if ((Flags & LONG_TYPE) == LONG_TYPE) {
606 Value = VA_ARG (Marker, UINT64);
607 } else {
608 Value = VA_ARG (Marker, UINTN);
609 }
610
611 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
612 UnicodeStr = TempBuffer;
613
614 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
615 Buffer[Index++] = *UnicodeStr;
616 }
617 break;
618
619 case 'd':
620 if ((Flags & LONG_TYPE) == LONG_TYPE) {
621 Value = VA_ARG (Marker, UINT64);
622 } else {
623 Value = (UINTN) VA_ARG (Marker, UINTN);
624 }
625
626 EfiValueToString (TempBuffer, Value, Flags, Width);
627 UnicodeStr = TempBuffer;
628
629 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
630 Buffer[Index++] = *UnicodeStr;
631 }
632 break;
633
634 case 's':
635 case 'S':
636 UnicodeStr = (CHAR16 *) VA_ARG (Marker, CHAR_W *);
637 if (UnicodeStr == NULL) {
638 UnicodeStr = L"<null string>";
639 }
640
641 for (Count = 0; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {
642 Buffer[Index++] = *UnicodeStr;
643 }
644 //
645 // Add padding if needed
646 //
647 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
648 Buffer[Index++] = ' ';
649 }
650
651 break;
652
653 case 'a':
654 AsciiStr = (CHAR8 *) VA_ARG (Marker, CHAR8 *);
655 if (AsciiStr == NULL) {
656 AsciiStr = (CHAR8 *) "<null string>";
657 }
658
659 for (Count = 0; (*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {
660 Buffer[Index++] = (CHAR_W) * AsciiStr;
661 }
662 //
663 // Add padding if needed
664 //
665 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
666 Buffer[Index++] = ' ';
667 }
668 break;
669
670 case 'c':
671 Buffer[Index++] = (CHAR_W) VA_ARG (Marker, UINTN);
672 break;
673
674 case 'g':
675 TmpGUID = VA_ARG (Marker, EFI_GUID *);
676 if (TmpGUID != NULL) {
677 Index += GuidToString (
678 TmpGUID,
679 &Buffer[Index],
680 BufferLeft
681 );
682 }
683 break;
684
685 case 't':
686 Index += TimeToString (
687 VA_ARG (Marker, EFI_TIME *),
688 &Buffer[Index],
689 BufferLeft
690 );
691 break;
692
693 case 'r':
694 Index += EfiStatusToString (
695 VA_ARG (Marker, EFI_STATUS),
696 &Buffer[Index],
697 BufferLeft
698 );
699 break;
700
701 case '%':
702 Buffer[Index++] = *Format;
703 break;
704
705 default:
706 //
707 // if the type is unknown print it to the screen
708 //
709 Buffer[Index++] = *Format;
710 }
711
712 BufferLeft = BufferSize - Index * sizeof (CHAR_W);
713 }
714 }
715
716 Buffer[Index++] = '\0';
717
718 return &Buffer[Index] - StartOfBuffer;
719 }
720
721 STATIC
722 CHAR_W *
723 GetFlagsAndWidth (
724 IN CHAR_W *Format,
725 OUT UINTN *Flags,
726 OUT UINTN *Width,
727 IN OUT VA_LIST *Marker
728 )
729 /*++
730
731 Routine Description:
732
733 VSPrint worker function that parses flag and width information from the
734 Format string and returns the next index into the Format string that needs
735 to be parsed. See file headed for details of Flag and Width.
736
737 Arguments:
738
739 Format - Current location in the VSPrint format string.
740
741 Flags - Returns flags
742
743 Width - Returns width of element
744
745 Marker - Vararg list that may be paritally consumed and returned.
746
747 Returns:
748
749 Pointer indexed into the Format string for all the information parsed
750 by this routine.
751
752 --*/
753 {
754 UINTN Count;
755 BOOLEAN Done;
756
757 *Flags = 0;
758 *Width = 0;
759 for (Done = FALSE; !Done;) {
760 Format++;
761
762 switch (*Format) {
763
764 case '-':
765 *Flags |= LEFT_JUSTIFY;
766 break;
767
768 case '+':
769 *Flags |= PREFIX_SIGN;
770 break;
771
772 case ' ':
773 *Flags |= PREFIX_BLANK;
774 break;
775
776 case ',':
777 *Flags |= COMMA_TYPE;
778 break;
779
780 case 'L':
781 case 'l':
782 *Flags |= LONG_TYPE;
783 break;
784
785 case '*':
786 *Width = VA_ARG (*Marker, UINTN);
787 break;
788
789 case '0':
790 *Flags |= PREFIX_ZERO;
791
792 case '1':
793 case '2':
794 case '3':
795 case '4':
796 case '5':
797 case '6':
798 case '7':
799 case '8':
800 case '9':
801 Count = 0;
802 do {
803 Count = (Count * 10) +*Format - '0';
804 Format++;
805 } while ((*Format >= '0') && (*Format <= '9'));
806 Format--;
807 *Width = Count;
808 break;
809
810 default:
811 Done = TRUE;
812 }
813 }
814
815 return Format;
816 }
817
818 STATIC
819 UINTN
820 GuidToString (
821 IN EFI_GUID *Guid,
822 IN CHAR_W *Buffer,
823 IN UINTN BufferSize
824 )
825 /*++
826
827 Routine Description:
828
829 VSPrint worker function that prints an EFI_GUID.
830
831 Arguments:
832
833 Guid - Pointer to GUID to print.
834
835 Buffer - Buffe to print Guid into.
836
837 BufferSize - Size of Buffer.
838
839 Returns:
840
841 Number of characters printed.
842
843 --*/
844 {
845 UINTN Size;
846
847 Size = SPrint (
848 Buffer,
849 BufferSize,
850 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
851 (UINTN)Guid->Data1,
852 (UINTN)Guid->Data2,
853 (UINTN)Guid->Data3,
854 (UINTN)Guid->Data4[0],
855 (UINTN)Guid->Data4[1],
856 (UINTN)Guid->Data4[2],
857 (UINTN)Guid->Data4[3],
858 (UINTN)Guid->Data4[4],
859 (UINTN)Guid->Data4[5],
860 (UINTN)Guid->Data4[6],
861 (UINTN)Guid->Data4[7]
862 );
863
864 //
865 // SPrint will null terminate the string. The -1 skips the null
866 //
867 return Size - 1;
868 }
869
870
871 STATIC
872 UINTN
873 TimeToString (
874 IN EFI_TIME *Time,
875 OUT CHAR_W *Buffer,
876 IN UINTN BufferSize
877 )
878 /*++
879
880 Routine Description:
881
882 VSPrint worker function that prints EFI_TIME.
883
884 Arguments:
885
886 Time - Pointer to EFI_TIME sturcture to print.
887
888 Buffer - Buffer to print Time into.
889
890 BufferSize - Size of Buffer.
891
892 Returns:
893
894 Number of characters printed.
895
896 --*/
897 {
898 UINTN Size;
899
900 Size = SPrint (
901 Buffer,
902 BufferSize,
903 STRING_W ("%02d/%02d/%04d %02d:%02d"),
904 (UINTN)Time->Month,
905 (UINTN)Time->Day,
906 (UINTN)Time->Year,
907 (UINTN)Time->Hour,
908 (UINTN)Time->Minute
909 );
910
911 //
912 // SPrint will null terminate the string. The -1 skips the null
913 //
914 return Size - 1;
915 }
916
917 STATIC
918 UINTN
919 EfiStatusToString (
920 IN EFI_STATUS Status,
921 OUT CHAR_W *Buffer,
922 IN UINTN BufferSize
923 )
924 /*++
925
926 Routine Description:
927
928 VSPrint worker function that prints EFI_STATUS as a string. If string is
929 not known a hex value will be printed.
930
931 Arguments:
932
933 Status - EFI_STATUS sturcture to print.
934
935 Buffer - Buffer to print EFI_STATUS message string into.
936
937 BufferSize - Size of Buffer.
938
939 Returns:
940
941 Number of characters printed.
942
943 --*/
944 {
945 UINTN Size;
946 CHAR8 *Desc;
947
948 Desc = NULL;
949
950 //
951 // Can't use global Status String Array as UINTN is not constant for EBC
952 //
953 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else
954 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else
955 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else
956 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else
957 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else
958 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else
959 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else
960 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else
961 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else
962 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else
963 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else
964 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else
965 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else
966 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else
967 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else
968 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else
969 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else
970 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else
971 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else
972 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else
973 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else
974 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else
975 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else
976 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else
977 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else
978 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else
979 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else
980 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else
981 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; }
982
983 //
984 // If we found a match, copy the message to the user's buffer. Otherwise
985 // sprint the hex status code to their buffer.
986 //
987 if (Desc != NULL) {
988 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);
989 } else {
990 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);
991 }
992
993 return Size - 1;
994 }