]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Print.c
Initialize the local variable before refer to them.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 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 Length of string printed to the console
162
163 --*/
164 {
165 VOID *Buffer;
166 EFI_STATUS Status;
167 UINTN Index;
168 CHAR16 *UnicodeWeight;
169 UINT32 HorizontalResolution;
170 UINT32 VerticalResolution;
171 UINT32 ColorDepth;
172 UINT32 RefreshRate;
173 UINTN BufferLen;
174 UINTN LineBufferLen;
175 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
176 EFI_HII_FONT_PROTOCOL *HiiFont;
177 EFI_IMAGE_OUTPUT *Blt;
178 EFI_FONT_DISPLAY_INFO *FontInfo;
179 #else
180 EFI_HII_PROTOCOL *Hii;
181 UINT16 GlyphWidth;
182 UINT32 GlyphStatus;
183 UINT16 StringIndex;
184 EFI_NARROW_GLYPH *Glyph;
185 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
186 #endif
187
188 //
189 // For now, allocate an arbitrarily long buffer
190 //
191 BufferLen = 0;
192 Buffer = EfiLibAllocateZeroPool (0x10000);
193 if (Buffer == NULL) {
194 return 0;
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 EfiLibSafeFreePool (LineBuffer);
375 #endif
376 gBS->FreePool (Buffer);
377
378 if (EFI_ERROR (Status)) {
379 return 0;
380 }
381
382 return BufferLen;
383 }
384
385
386 UINTN
387 PrintXY (
388 IN UINTN X,
389 IN UINTN Y,
390 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
391 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
392 IN CHAR_W *Fmt,
393 ...
394 )
395 /*++
396
397 Routine Description:
398
399 Prints a formatted unicode string to the default console
400
401 Arguments:
402
403 X - X coordinate to start printing
404
405 Y - Y coordinate to start printing
406
407 ForeGround - Foreground color
408
409 BackGround - Background color
410
411 Fmt - Format string
412
413 ... - Print arguments
414
415 Returns:
416
417 Length of string printed to the console
418
419 --*/
420 {
421 EFI_HANDLE Handle;
422 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
423 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
424 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
425 EFI_STATUS Status;
426 VA_LIST Args;
427
428 VA_START (Args, Fmt);
429
430 Handle = gST->ConsoleOutHandle;
431
432 GraphicsOutput = NULL;
433 UgaDraw = NULL;
434 Status = gBS->HandleProtocol (
435 Handle,
436 &gEfiGraphicsOutputProtocolGuid,
437 (VOID**)&GraphicsOutput
438 );
439
440 if (EFI_ERROR (Status) || (GraphicsOutput == NULL)) {
441 GraphicsOutput = NULL;
442
443 Status = gBS->HandleProtocol (
444 Handle,
445 &gEfiUgaDrawProtocolGuid,
446 (VOID**)&UgaDraw
447 );
448
449 if (EFI_ERROR (Status) || (UgaDraw == NULL)) {
450 return 0;
451 }
452 }
453
454 Sto = NULL;
455 Status = gBS->HandleProtocol (
456 Handle,
457 &gEfiSimpleTextOutProtocolGuid,
458 (VOID**)&Sto
459 );
460
461 if (EFI_ERROR (Status) || (Sto == NULL)) {
462 return 0;
463 }
464
465 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
466 }
467
468
469 UINTN
470 SPrint (
471 OUT CHAR_W *Buffer,
472 IN UINTN BufferSize,
473 IN CONST CHAR_W *Format,
474 ...
475 )
476 /*++
477
478 Routine Description:
479
480 SPrint function to process format and place the results in Buffer.
481
482 Arguments:
483
484 Buffer - Wide char buffer to print the results of the parsing of Format into.
485
486 BufferSize - Maximum number of characters to put into buffer. Zero means no
487 limit.
488
489 Format - Format string see file header for more details.
490
491 ... - Vararg list consumed by processing Format.
492
493 Returns:
494
495 Number of characters printed.
496
497 --*/
498 {
499 UINTN Return;
500 VA_LIST Marker;
501
502 VA_START (Marker, Format);
503 Return = VSPrint (Buffer, BufferSize, Format, Marker);
504 VA_END (Marker);
505
506 return Return;
507 }
508
509 UINTN
510 EFIAPI
511 VSPrint (
512 OUT CHAR_W *StartOfBuffer,
513 IN UINTN BufferSize,
514 IN CONST CHAR_W *FormatString,
515 IN VA_LIST Marker
516 )
517 /*++
518
519 Routine Description:
520
521 VSPrint function to process format and place the results in Buffer. Since a
522 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
523 this is the main print working routine
524
525 Arguments:
526
527 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
528
529 BufferSize - Maximum number of characters to put into buffer. Zero means
530 no limit.
531
532 FormatString - Unicode format string see file header for more details.
533
534 Marker - Vararg list consumed by processing Format.
535
536 Returns:
537
538 Number of characters printed.
539
540 --*/
541 {
542 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
543 CHAR_W *Buffer;
544 CHAR8 *AsciiStr;
545 CHAR16 *UnicodeStr;
546 CHAR_W *Format;
547 UINTN Index;
548 UINTN Flags;
549 UINTN Width;
550 UINTN Count;
551 UINTN NumberOfCharacters;
552 UINTN BufferLeft;
553 UINT64 Value;
554 EFI_GUID *TmpGUID;
555
556 //
557 // Process the format string. Stop if Buffer is over run.
558 //
559
560 Buffer = StartOfBuffer;
561 Format = (CHAR_W *) FormatString;
562 NumberOfCharacters = BufferSize / sizeof (CHAR_W);
563 BufferLeft = BufferSize;
564 for (Index = 0; (*Format != '\0') && (Index < NumberOfCharacters - 1); Format++) {
565 if (*Format != '%') {
566 if ((*Format == '\n') && (Index < NumberOfCharacters - 2)) {
567 //
568 // If carage return add line feed
569 //
570 Buffer[Index++] = '\r';
571 BufferLeft -= sizeof (CHAR_W);
572 }
573
574 Buffer[Index++] = *Format;
575 BufferLeft -= sizeof (CHAR_W);
576 } else {
577
578 //
579 // Now it's time to parse what follows after %
580 //
581 Format = GetFlagsAndWidth (Format, &Flags, &Width, &Marker);
582 switch (*Format) {
583 case 'p':
584 //
585 // Flag space, +, 0, L & l are invalid for type p.
586 //
587 Flags &= ~(PREFIX_BLANK| PREFIX_SIGN | LONG_TYPE);
588 if (sizeof (VOID *) > 4) {
589 Flags |= LONG_TYPE;
590 Value = VA_ARG (Marker, UINT64);
591 } else {
592 Value = VA_ARG (Marker, UINTN);
593 }
594 Flags |= PREFIX_ZERO;
595
596 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
597 UnicodeStr = TempBuffer;
598
599 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
600 Buffer[Index++] = *UnicodeStr;
601 }
602 break;
603
604 case 'X':
605 Flags |= PREFIX_ZERO;
606 Width = sizeof (UINT64) * 2;
607
608 //
609 // break skiped on purpose
610 //
611 case 'x':
612 if ((Flags & LONG_TYPE) == LONG_TYPE) {
613 Value = VA_ARG (Marker, UINT64);
614 } else {
615 Value = VA_ARG (Marker, UINTN);
616 }
617
618 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
619 UnicodeStr = TempBuffer;
620
621 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
622 Buffer[Index++] = *UnicodeStr;
623 }
624 break;
625
626 case 'd':
627 if ((Flags & LONG_TYPE) == LONG_TYPE) {
628 Value = VA_ARG (Marker, UINT64);
629 } else {
630 Value = (UINTN) VA_ARG (Marker, UINTN);
631 }
632
633 EfiValueToString (TempBuffer, Value, Flags, Width);
634 UnicodeStr = TempBuffer;
635
636 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
637 Buffer[Index++] = *UnicodeStr;
638 }
639 break;
640
641 case 's':
642 case 'S':
643 UnicodeStr = (CHAR16 *) VA_ARG (Marker, CHAR_W *);
644 if (UnicodeStr == NULL) {
645 UnicodeStr = L"<null string>";
646 }
647
648 for (Count = 0; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {
649 Buffer[Index++] = *UnicodeStr;
650 }
651 //
652 // Add padding if needed
653 //
654 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
655 Buffer[Index++] = ' ';
656 }
657
658 break;
659
660 case 'a':
661 AsciiStr = (CHAR8 *) VA_ARG (Marker, CHAR8 *);
662 if (AsciiStr == NULL) {
663 AsciiStr = (CHAR8 *) "<null string>";
664 }
665
666 for (Count = 0; (*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {
667 Buffer[Index++] = (CHAR_W) * AsciiStr;
668 }
669 //
670 // Add padding if needed
671 //
672 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
673 Buffer[Index++] = ' ';
674 }
675 break;
676
677 case 'c':
678 Buffer[Index++] = (CHAR_W) VA_ARG (Marker, UINTN);
679 break;
680
681 case 'g':
682 TmpGUID = VA_ARG (Marker, EFI_GUID *);
683 if (TmpGUID != NULL) {
684 Index += GuidToString (
685 TmpGUID,
686 &Buffer[Index],
687 BufferLeft
688 );
689 }
690 break;
691
692 case 't':
693 Index += TimeToString (
694 VA_ARG (Marker, EFI_TIME *),
695 &Buffer[Index],
696 BufferLeft
697 );
698 break;
699
700 case 'r':
701 Index += EfiStatusToString (
702 VA_ARG (Marker, EFI_STATUS),
703 &Buffer[Index],
704 BufferLeft
705 );
706 break;
707
708 case '%':
709 Buffer[Index++] = *Format;
710 break;
711
712 default:
713 //
714 // if the type is unknown print it to the screen
715 //
716 Buffer[Index++] = *Format;
717 }
718
719 BufferLeft = BufferSize - Index * sizeof (CHAR_W);
720 }
721 }
722
723 Buffer[Index++] = '\0';
724
725 return &Buffer[Index] - StartOfBuffer;
726 }
727
728 STATIC
729 CHAR_W *
730 GetFlagsAndWidth (
731 IN CHAR_W *Format,
732 OUT UINTN *Flags,
733 OUT UINTN *Width,
734 IN OUT VA_LIST *Marker
735 )
736 /*++
737
738 Routine Description:
739
740 VSPrint worker function that parses flag and width information from the
741 Format string and returns the next index into the Format string that needs
742 to be parsed. See file headed for details of Flag and Width.
743
744 Arguments:
745
746 Format - Current location in the VSPrint format string.
747
748 Flags - Returns flags
749
750 Width - Returns width of element
751
752 Marker - Vararg list that may be paritally consumed and returned.
753
754 Returns:
755
756 Pointer indexed into the Format string for all the information parsed
757 by this routine.
758
759 --*/
760 {
761 UINTN Count;
762 BOOLEAN Done;
763
764 *Flags = 0;
765 *Width = 0;
766 for (Done = FALSE; !Done;) {
767 Format++;
768
769 switch (*Format) {
770
771 case '-':
772 *Flags |= LEFT_JUSTIFY;
773 break;
774
775 case '+':
776 *Flags |= PREFIX_SIGN;
777 break;
778
779 case ' ':
780 *Flags |= PREFIX_BLANK;
781 break;
782
783 case ',':
784 *Flags |= COMMA_TYPE;
785 break;
786
787 case 'L':
788 case 'l':
789 *Flags |= LONG_TYPE;
790 break;
791
792 case '*':
793 *Width = VA_ARG (*Marker, UINTN);
794 break;
795
796 case '0':
797 *Flags |= PREFIX_ZERO;
798
799 case '1':
800 case '2':
801 case '3':
802 case '4':
803 case '5':
804 case '6':
805 case '7':
806 case '8':
807 case '9':
808 Count = 0;
809 do {
810 Count = (Count * 10) +*Format - '0';
811 Format++;
812 } while ((*Format >= '0') && (*Format <= '9'));
813 Format--;
814 *Width = Count;
815 break;
816
817 default:
818 Done = TRUE;
819 }
820 }
821
822 return Format;
823 }
824
825 STATIC
826 UINTN
827 GuidToString (
828 IN EFI_GUID *Guid,
829 IN CHAR_W *Buffer,
830 IN UINTN BufferSize
831 )
832 /*++
833
834 Routine Description:
835
836 VSPrint worker function that prints an EFI_GUID.
837
838 Arguments:
839
840 Guid - Pointer to GUID to print.
841
842 Buffer - Buffe to print Guid into.
843
844 BufferSize - Size of Buffer.
845
846 Returns:
847
848 Number of characters printed.
849
850 --*/
851 {
852 UINTN Size;
853
854 Size = SPrint (
855 Buffer,
856 BufferSize,
857 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
858 (UINTN)Guid->Data1,
859 (UINTN)Guid->Data2,
860 (UINTN)Guid->Data3,
861 (UINTN)Guid->Data4[0],
862 (UINTN)Guid->Data4[1],
863 (UINTN)Guid->Data4[2],
864 (UINTN)Guid->Data4[3],
865 (UINTN)Guid->Data4[4],
866 (UINTN)Guid->Data4[5],
867 (UINTN)Guid->Data4[6],
868 (UINTN)Guid->Data4[7]
869 );
870
871 //
872 // SPrint will null terminate the string. The -1 skips the null
873 //
874 return Size - 1;
875 }
876
877
878 STATIC
879 UINTN
880 TimeToString (
881 IN EFI_TIME *Time,
882 OUT CHAR_W *Buffer,
883 IN UINTN BufferSize
884 )
885 /*++
886
887 Routine Description:
888
889 VSPrint worker function that prints EFI_TIME.
890
891 Arguments:
892
893 Time - Pointer to EFI_TIME sturcture to print.
894
895 Buffer - Buffer to print Time into.
896
897 BufferSize - Size of Buffer.
898
899 Returns:
900
901 Number of characters printed.
902
903 --*/
904 {
905 UINTN Size;
906
907 Size = SPrint (
908 Buffer,
909 BufferSize,
910 STRING_W ("%02d/%02d/%04d %02d:%02d"),
911 (UINTN)Time->Month,
912 (UINTN)Time->Day,
913 (UINTN)Time->Year,
914 (UINTN)Time->Hour,
915 (UINTN)Time->Minute
916 );
917
918 //
919 // SPrint will null terminate the string. The -1 skips the null
920 //
921 return Size - 1;
922 }
923
924 STATIC
925 UINTN
926 EfiStatusToString (
927 IN EFI_STATUS Status,
928 OUT CHAR_W *Buffer,
929 IN UINTN BufferSize
930 )
931 /*++
932
933 Routine Description:
934
935 VSPrint worker function that prints EFI_STATUS as a string. If string is
936 not known a hex value will be printed.
937
938 Arguments:
939
940 Status - EFI_STATUS sturcture to print.
941
942 Buffer - Buffer to print EFI_STATUS message string into.
943
944 BufferSize - Size of Buffer.
945
946 Returns:
947
948 Number of characters printed.
949
950 --*/
951 {
952 UINTN Size;
953 CHAR8 *Desc;
954
955 Desc = NULL;
956
957 //
958 // Can't use global Status String Array as UINTN is not constant for EBC
959 //
960 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else
961 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else
962 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else
963 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else
964 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else
965 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else
966 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else
967 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else
968 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else
969 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else
970 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else
971 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else
972 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else
973 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else
974 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else
975 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else
976 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else
977 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else
978 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else
979 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else
980 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else
981 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else
982 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else
983 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else
984 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else
985 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else
986 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else
987 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else
988 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; }
989
990 //
991 // If we found a match, copy the message to the user's buffer. Otherwise
992 // sprint the hex status code to their buffer.
993 //
994 if (Desc != NULL) {
995 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);
996 } else {
997 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);
998 }
999
1000 return Size - 1;
1001 }