3 Copyright (c) 2004, 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
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.
18 Basic Ascii AvSPrintf() function named AvSPrint(). AvSPrint() enables very
19 simple implemenation of debug prints.
21 You can not Print more than PEI_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
24 AvSPrint format specification has the follwoing form
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
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
67 IN OUT VA_LIST
*Marker
100 IN OUT CHAR8
*Buffer
,
107 IN EFI_STATUS Status
,
117 IN CONST CHAR8
*Format
,
124 ASPrint function to process format and place the results in Buffer.
128 Buffer - Ascii buffer to print the results of the parsing of Format into.
130 BufferSize - Maximum number of characters to put into buffer. Zero means no
133 Format - Ascii format string see file header for more details.
135 ... - Vararg list consumed by processing Format.
139 Number of characters printed.
146 VA_START(Marker
, Format
);
147 Return
= AvSPrint(Buffer
, BufferSize
, Format
, Marker
);
156 OUT CHAR8
*StartOfBuffer
,
158 IN CONST CHAR8
*FormatString
,
165 AvSPrint function to process format and place the results in Buffer. Since a
166 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
167 this is the main print working routine
171 StartOfBuffer - Ascii buffer to print the results of the parsing of Format into.
173 BufferSize - Maximum number of characters to put into buffer. Zero means
176 FormatString - Ascii format string see file header for more details.
178 Marker - Vararg list consumed by processing Format.
182 Number of characters printed.
196 // Process the format string. Stop if Buffer is over run.
199 Buffer
= StartOfBuffer
;
200 Format
= (CHAR8
*)FormatString
;
201 for (Index
= 0; (*Format
!= '\0') && (Index
< BufferSize
); Format
++) {
202 if (*Format
!= '%') {
203 if (*Format
== '\n') {
205 // If carage return add line feed
207 Buffer
[Index
++] = '\r';
209 Buffer
[Index
++] = *Format
;
213 // Now it's time to parse what follows after %
215 Format
= GetFlagsAndWidth (Format
, &Flags
, &Width
, &Marker
);
218 Flags
|= PREFIX_ZERO
;
219 Width
= sizeof (UINT64
) * 2;
221 // break skiped on purpose
224 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
225 Value
= VA_ARG (Marker
, UINT64
);
227 Value
= VA_ARG (Marker
, UINTN
);
229 Index
+= ValueTomHexStr (&Buffer
[Index
], Value
, Flags
, Width
);
233 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
234 Value
= VA_ARG (Marker
, UINT64
);
236 Value
= (UINTN
)VA_ARG (Marker
, UINTN
);
238 Index
+= ValueToString (&Buffer
[Index
], Value
, Flags
, Width
);
243 UnicodeStr
= (CHAR16
*)VA_ARG (Marker
, CHAR16
*);
244 if (UnicodeStr
== NULL
) {
245 UnicodeStr
= L
"<null string>";
247 for ( ;*UnicodeStr
!= '\0'; UnicodeStr
++) {
248 Buffer
[Index
++] = (CHAR8
)*UnicodeStr
;
253 AsciiStr
= (CHAR8
*)VA_ARG (Marker
, CHAR8
*);
254 if (AsciiStr
== NULL
) {
255 AsciiStr
= "<null string>";
257 while (*AsciiStr
!= '\0') {
258 Buffer
[Index
++] = *AsciiStr
++;
263 Buffer
[Index
++] = (CHAR8
)VA_ARG (Marker
, UINTN
);
267 Index
+= GuidToString (
268 VA_ARG (Marker
, EFI_GUID
*),
275 Index
+= TimeToString (
276 VA_ARG (Marker
, EFI_TIME
*),
283 Index
+= EfiStatusToString (
284 VA_ARG (Marker
, EFI_STATUS
),
291 Buffer
[Index
++] = *Format
;
296 // if the type is unknown print it to the screen
298 Buffer
[Index
++] = *Format
;
303 Buffer
[Index
++] = '\0';
305 return &Buffer
[Index
] - StartOfBuffer
;
316 IN OUT VA_LIST
*Marker
322 AvSPrint worker function that parses flag and width information from the
323 Format string and returns the next index into the Format string that needs
324 to be parsed. See file headed for details of Flag and Width.
328 Format - Current location in the AvSPrint format string.
330 Flags - Returns flags
332 Width - Returns width of element
334 Marker - Vararg list that may be paritally consumed and returned.
338 Pointer indexed into the Format string for all the information parsed
348 for (Done
= FALSE
; !Done
; ) {
353 case '-': *Flags
|= LEFT_JUSTIFY
; break;
354 case '+': *Flags
|= PREFIX_SIGN
; break;
355 case ' ': *Flags
|= PREFIX_BLANK
; break;
356 case ',': *Flags
|= COMMA_TYPE
; break;
358 case 'l': *Flags
|= LONG_TYPE
; break;
361 *Width
= VA_ARG (*Marker
, UINTN
);
365 *Flags
|= PREFIX_ZERO
;
377 Count
= (Count
* 10) + *Format
- '0';
379 } while ((*Format
>= '0') && (*Format
<= '9'));
391 static CHAR8 mHexStr
[] = { '0','1','2','3','4','5','6','7',
392 '8','9','A','B','C','D','E','F' };
397 IN OUT CHAR8
*Buffer
,
406 AvSPrint worker function that prints a Value as a hex number in Buffer
410 Buffer - Location to place ascii hex string of Value.
412 Value - Hex value to convert to a string in Buffer.
414 Flags - Flags to use in printing Hex string, see file header for details.
416 Width - Width of hex value.
420 Number of characters printed.
424 CHAR8 TempBuffer
[30];
431 TempStr
= TempBuffer
;
435 // Count starts at one since we will null terminate. Each iteration of the
436 // loop picks off one nibble. Oh yea TempStr ends up backwards
440 *(TempStr
++) = mHexStr
[Value
& 0x0f];
441 Value
= RShiftU64 (Value
, 4);
443 } while (Value
!= 0);
445 if (Flags
& PREFIX_ZERO
) {
447 } else if (!(Flags
& LEFT_JUSTIFY
)) {
452 for (Index
= Count
; Index
< Width
; Index
++) {
453 *(TempStr
++) = Prefix
;
457 // Reverse temp string into Buffer.
459 while (TempStr
!= TempBuffer
) {
460 *(BufferPtr
++) = *(--TempStr
);
470 IN OUT CHAR8
*Buffer
,
479 AvSPrint worker function that prints a Value as a decimal number in Buffer
483 Buffer - Location to place ascii decimal number string of Value.
485 Value - Decimal value to convert to a string in Buffer.
487 Flags - Flags to use in printing decimal string, see file header for details.
489 Width - Width of hex value.
493 Number of characters printed.
497 CHAR8 TempBuffer
[30];
503 TempStr
= TempBuffer
;
508 *(BufferPtr
++) = '-';
514 Value
= (INT64
)DivU64x32 ((UINT64
)Value
, 10, &Remainder
);
515 *(TempStr
++) = (CHAR8
)(Remainder
+ '0');
517 if ((Flags
& COMMA_TYPE
) == COMMA_TYPE
) {
518 if (Count
% 3 == 0) {
522 } while (Value
!= 0);
525 // Reverse temp string into Buffer.
527 while (TempStr
!= TempBuffer
) {
528 *(BufferPtr
++) = *(--TempStr
);
546 AvSPrint worker function that prints an EFI_GUID.
550 Guid - Pointer to GUID to print.
552 Buffer - Buffe to print Guid into.
554 BufferSize - Size of Buffer.
558 Number of characters printed.
567 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
582 // ASPrint will null terminate the string. The -1 skips the null
599 AvSPrint worker function that prints EFI_TIME.
603 Time - Pointer to EFI_TIME sturcture to print.
605 Buffer - Buffer to print Time into.
607 BufferSize - Size of Buffer.
611 Number of characters printed.
620 "%02d/%02d/%04d %02d:%02d",
629 // ASPrint will null terminate the string. The -1 skips the null
637 IN EFI_STATUS Status
,
645 AvSPrint worker function that prints EFI_STATUS as a string. If string is
646 not known a hex value will be printed.
650 Status - EFI_STATUS sturcture to print.
652 Buffer - Buffer to print EFI_STATUS message string into.
654 BufferSize - Size of Buffer.
658 Number of characters printed.
665 if (Status
== EFI_SUCCESS
) {
667 } else if (Status
== EFI_LOAD_ERROR
) {
669 } else if (Status
== EFI_INVALID_PARAMETER
) {
670 Desc
= "Invalid Parameter";
671 } else if (Status
== EFI_UNSUPPORTED
) {
672 Desc
= "Unsupported";
673 } else if (Status
== EFI_BAD_BUFFER_SIZE
) {
674 Desc
= "Bad Buffer Size";
675 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
676 Desc
= "Buffer Too Small";
677 } else if (Status
== EFI_NOT_READY
) {
679 } else if (Status
== EFI_DEVICE_ERROR
) {
680 Desc
= "Device Error";
681 } else if (Status
== EFI_WRITE_PROTECTED
) {
682 Desc
= "Write Protected";
683 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
684 Desc
= "Out of Resources";
685 } else if (Status
== EFI_VOLUME_CORRUPTED
) {
686 Desc
= "Volume Corrupt";
687 } else if (Status
== EFI_VOLUME_FULL
) {
688 Desc
= "Volume Full";
689 } else if (Status
== EFI_NO_MEDIA
) {
691 } else if (Status
== EFI_MEDIA_CHANGED
) {
692 Desc
= "Media changed";
693 } else if (Status
== EFI_NOT_FOUND
) {
695 } else if (Status
== EFI_ACCESS_DENIED
) {
696 Desc
= "Access Denied";
697 } else if (Status
== EFI_NO_RESPONSE
) {
698 Desc
= "No Response";
699 } else if (Status
== EFI_NO_MAPPING
) {
701 } else if (Status
== EFI_TIMEOUT
) {
703 } else if (Status
== EFI_NOT_STARTED
) {
704 Desc
= "Not started";
705 } else if (Status
== EFI_ALREADY_STARTED
) {
706 Desc
= "Already started";
707 } else if (Status
== EFI_ABORTED
) {
709 } else if (Status
== EFI_ICMP_ERROR
) {
711 } else if (Status
== EFI_TFTP_ERROR
) {
713 } else if (Status
== EFI_PROTOCOL_ERROR
) {
714 Desc
= "Protocol Error";
715 } else if (Status
== EFI_WARN_UNKNOWN_GLYPH
) {
716 Desc
= "Warning Unknown Glyph";
717 } else if (Status
== EFI_WARN_DELETE_FAILURE
) {
718 Desc
= "Warning Delete Failure";
719 } else if (Status
== EFI_WARN_WRITE_FAILURE
) {
720 Desc
= "Warning Write Failure";
721 } else if (Status
== EFI_WARN_BUFFER_TOO_SMALL
) {
722 Desc
= "Warning Buffer Too Small";
727 // If we found a match, copy the message to the user's buffer. Otherwise
728 // sprint the hex status code to their buffer.
731 Size
= ASPrint (Buffer
, BufferSize
, "%a", Desc
);
733 Size
= ASPrint (Buffer
, BufferSize
, "%X", Status
);