3 Copyright (c) 2004, 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
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 'p' - arugment is VOID *; printed as hex number
43 'X' - argument is a UINTN hex number, prefix '0'
44 'x' - argument is a hex number
45 'd' - argument is a decimal number
46 'a' - argument is an ascii string
47 'S', 's' - argument is an Unicode string
48 'g' - argument is a pointer to an EFI_GUID
49 't' - argument is a pointer to an EFI_TIME structure
50 'c' - argument is an ascii character
51 '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.
186 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
200 // Process the format string. Stop if Buffer is over run.
202 Buffer
= StartOfBuffer
;
203 Format
= (CHAR8
*) FormatString
;
204 BufferLeft
= BufferSize
;
205 for (Index
= 0; (*Format
!= '\0') && (Index
< BufferSize
- 1); Format
++) {
206 if (*Format
!= '%') {
207 if ((*Format
== '\n') && (Index
< BufferSize
- 2)) {
209 // If carage return add line feed
211 Buffer
[Index
++] = '\r';
212 BufferLeft
-= sizeof (CHAR8
);
215 Buffer
[Index
++] = *Format
;
216 BufferLeft
-= sizeof (CHAR8
);
220 // Now it's time to parse what follows after %
222 Format
= GetFlagsAndWidth (Format
, &Flags
, &Width
, &Marker
);
226 // Flag space, +, 0, L & l are invalid for type p.
228 Flags
&= ~(PREFIX_BLANK
| PREFIX_SIGN
| LONG_TYPE
);
229 if (sizeof (VOID
*) > 4) {
231 Value
= VA_ARG (Marker
, UINT64
);
233 Value
= VA_ARG (Marker
, UINTN
);
235 Flags
|= PREFIX_ZERO
;
237 ValueTomHexStr (TempBuffer
, Value
, Flags
, Width
);
238 AsciiStr
= TempBuffer
;
240 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
241 Buffer
[Index
++] = *AsciiStr
;
245 Flags
|= PREFIX_ZERO
;
246 Width
= sizeof (UINT64
) * 2;
249 // break skiped on purpose
252 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
253 Value
= VA_ARG (Marker
, UINT64
);
255 Value
= VA_ARG (Marker
, UINTN
);
258 ValueTomHexStr (TempBuffer
, Value
, Flags
, Width
);
259 AsciiStr
= TempBuffer
;
261 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
262 Buffer
[Index
++] = *AsciiStr
;
267 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
268 Value
= VA_ARG (Marker
, UINT64
);
270 Value
= (UINTN
) VA_ARG (Marker
, UINTN
);
273 ValueToString (TempBuffer
, Value
, Flags
, Width
);
274 AsciiStr
= TempBuffer
;
276 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
277 Buffer
[Index
++] = *AsciiStr
;
283 UnicodeStr
= (CHAR16
*) VA_ARG (Marker
, CHAR8
*);
284 if (UnicodeStr
== NULL
) {
285 UnicodeStr
= L
"<null string>";
288 for (Count
= 0; (*UnicodeStr
!= '\0') && (Index
< BufferSize
- 1); UnicodeStr
++, Count
++) {
289 Buffer
[Index
++] = (CHAR8
) *UnicodeStr
;
292 // Add padding if needed
294 for (; (Count
< Width
) && (Index
< BufferSize
- 1); Count
++) {
295 Buffer
[Index
++] = ' ';
301 AsciiStr
= (CHAR8
*) VA_ARG (Marker
, CHAR8
*);
302 if (AsciiStr
== NULL
) {
303 AsciiStr
= "<null string>";
306 for (Count
= 0; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++, Count
++) {
307 Buffer
[Index
++] = *AsciiStr
;
310 // Add padding if needed
312 for (; (Count
< Width
) && (Index
< BufferSize
- 1); Count
++) {
313 Buffer
[Index
++] = ' ';
318 Buffer
[Index
++] = (CHAR8
) VA_ARG (Marker
, UINTN
);
322 TmpGUID
= VA_ARG (Marker
, EFI_GUID
*);
323 if (TmpGUID
!= NULL
) {
324 Index
+= GuidToString (
333 Index
+= TimeToString (
334 VA_ARG (Marker
, EFI_TIME
*),
341 Index
+= EfiStatusToString (
342 VA_ARG (Marker
, EFI_STATUS
),
349 Buffer
[Index
++] = *Format
;
354 // if the type is unknown print it to the screen
356 Buffer
[Index
++] = *Format
;
359 BufferLeft
= BufferSize
- Index
;
363 Buffer
[Index
++] = '\0';
365 return &Buffer
[Index
] - StartOfBuffer
;
376 IN OUT VA_LIST
*Marker
382 AvSPrint worker function that parses flag and width information from the
383 Format string and returns the next index into the Format string that needs
384 to be parsed. See file headed for details of Flag and Width.
388 Format - Current location in the AvSPrint format string.
390 Flags - Returns flags
392 Width - Returns width of element
394 Marker - Vararg list that may be paritally consumed and returned.
398 Pointer indexed into the Format string for all the information parsed
408 for (Done
= FALSE
; !Done
; ) {
413 case '-': *Flags
|= LEFT_JUSTIFY
; break;
414 case '+': *Flags
|= PREFIX_SIGN
; break;
415 case ' ': *Flags
|= PREFIX_BLANK
; break;
416 case ',': *Flags
|= COMMA_TYPE
; break;
418 case 'l': *Flags
|= LONG_TYPE
; break;
421 *Width
= VA_ARG (*Marker
, UINTN
);
425 *Flags
|= PREFIX_ZERO
;
437 Count
= (Count
* 10) + *Format
- '0';
439 } while ((*Format
>= '0') && (*Format
<= '9'));
451 static CHAR8 mHexStr
[] = { '0','1','2','3','4','5','6','7',
452 '8','9','A','B','C','D','E','F' };
457 IN OUT CHAR8
*Buffer
,
466 AvSPrint worker function that prints a Value as a hex number in Buffer
470 Buffer - Location to place ascii hex string of Value.
472 Value - Hex value to convert to a string in Buffer.
474 Flags - Flags to use in printing Hex string, see file header for details.
476 Width - Width of hex value.
480 Number of characters printed.
484 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
491 TempStr
= TempBuffer
;
495 // Count starts at one since we will null terminate. Each iteration of the
496 // loop picks off one nibble. Oh yea TempStr ends up backwards
500 *(TempStr
++) = mHexStr
[Value
& 0x0f];
501 Value
= RShiftU64 (Value
, 4);
503 } while (Value
!= 0);
505 if (Flags
& PREFIX_ZERO
) {
507 } else if (!(Flags
& LEFT_JUSTIFY
)) {
512 for (Index
= Count
; Index
< Width
; Index
++) {
513 *(TempStr
++) = Prefix
;
517 // Reverse temp string into Buffer.
519 if (Width
> 0 && (UINTN
) (TempStr
- TempBuffer
) > Width
) {
520 TempStr
= TempBuffer
+ Width
;
523 while (TempStr
!= TempBuffer
) {
524 *(BufferPtr
++) = *(--TempStr
);
535 IN OUT CHAR8
*Buffer
,
544 AvSPrint worker function that prints a Value as a decimal number in Buffer
548 Buffer - Location to place ascii decimal number string of Value.
550 Value - Decimal value to convert to a string in Buffer.
552 Flags - Flags to use in printing decimal string, see file header for details.
554 Width - Width of hex value.
558 Number of characters printed.
562 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
572 TempStr
= TempBuffer
;
583 Value
= (INT64
)DivU64x32 ((UINT64
)Value
, 10, &Remainder
);
584 *(TempStr
++) = (CHAR8
)(Remainder
+ '0');
587 if ((Flags
& COMMA_TYPE
) == COMMA_TYPE
) {
588 if (NumberCount
% 3 == 0 && Value
!= 0) {
593 } while (Value
!= 0);
596 *(BufferPtr
++) = '-';
601 // Reverse temp string into Buffer.
603 if (Width
> 0 && (UINTN
) (TempStr
- TempBuffer
) > Width
) {
604 TempStr
= TempBuffer
+ Width
;
607 while (TempStr
!= TempBuffer
) {
608 *(BufferPtr
++) = *(--TempStr
);
626 AvSPrint worker function that prints an EFI_GUID.
630 Guid - Pointer to GUID to print.
632 Buffer - Buffe to print Guid into.
634 BufferSize - Size of Buffer.
638 Number of characters printed.
647 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
651 (UINTN
)Guid
->Data4
[0],
652 (UINTN
)Guid
->Data4
[1],
653 (UINTN
)Guid
->Data4
[2],
654 (UINTN
)Guid
->Data4
[3],
655 (UINTN
)Guid
->Data4
[4],
656 (UINTN
)Guid
->Data4
[5],
657 (UINTN
)Guid
->Data4
[6],
658 (UINTN
)Guid
->Data4
[7]
662 // ASPrint will null terminate the string. The -1 skips the null
679 AvSPrint worker function that prints EFI_TIME.
683 Time - Pointer to EFI_TIME sturcture to print.
685 Buffer - Buffer to print Time into.
687 BufferSize - Size of Buffer.
691 Number of characters printed.
700 "%02d/%02d/%04d %02d:%02d",
709 // ASPrint will null terminate the string. The -1 skips the null
717 IN EFI_STATUS Status
,
725 AvSPrint worker function that prints EFI_STATUS as a string. If string is
726 not known a hex value will be printed.
730 Status - EFI_STATUS sturcture to print.
732 Buffer - Buffer to print EFI_STATUS message string into.
734 BufferSize - Size of Buffer.
738 Number of characters printed.
745 if (Status
== EFI_SUCCESS
) {
747 } else if (Status
== EFI_LOAD_ERROR
) {
749 } else if (Status
== EFI_INVALID_PARAMETER
) {
750 Desc
= "Invalid Parameter";
751 } else if (Status
== EFI_UNSUPPORTED
) {
752 Desc
= "Unsupported";
753 } else if (Status
== EFI_BAD_BUFFER_SIZE
) {
754 Desc
= "Bad Buffer Size";
755 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
756 Desc
= "Buffer Too Small";
757 } else if (Status
== EFI_NOT_READY
) {
759 } else if (Status
== EFI_DEVICE_ERROR
) {
760 Desc
= "Device Error";
761 } else if (Status
== EFI_WRITE_PROTECTED
) {
762 Desc
= "Write Protected";
763 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
764 Desc
= "Out of Resources";
765 } else if (Status
== EFI_VOLUME_CORRUPTED
) {
766 Desc
= "Volume Corrupt";
767 } else if (Status
== EFI_VOLUME_FULL
) {
768 Desc
= "Volume Full";
769 } else if (Status
== EFI_NO_MEDIA
) {
771 } else if (Status
== EFI_MEDIA_CHANGED
) {
772 Desc
= "Media changed";
773 } else if (Status
== EFI_NOT_FOUND
) {
775 } else if (Status
== EFI_ACCESS_DENIED
) {
776 Desc
= "Access Denied";
777 } else if (Status
== EFI_NO_RESPONSE
) {
778 Desc
= "No Response";
779 } else if (Status
== EFI_NO_MAPPING
) {
781 } else if (Status
== EFI_TIMEOUT
) {
783 } else if (Status
== EFI_NOT_STARTED
) {
784 Desc
= "Not started";
785 } else if (Status
== EFI_ALREADY_STARTED
) {
786 Desc
= "Already started";
787 } else if (Status
== EFI_ABORTED
) {
789 } else if (Status
== EFI_ICMP_ERROR
) {
791 } else if (Status
== EFI_TFTP_ERROR
) {
793 } else if (Status
== EFI_PROTOCOL_ERROR
) {
794 Desc
= "Protocol Error";
795 } else if (Status
== EFI_WARN_UNKNOWN_GLYPH
) {
796 Desc
= "Warning Unknown Glyph";
797 } else if (Status
== EFI_WARN_DELETE_FAILURE
) {
798 Desc
= "Warning Delete Failure";
799 } else if (Status
== EFI_WARN_WRITE_FAILURE
) {
800 Desc
= "Warning Write Failure";
801 } else if (Status
== EFI_WARN_BUFFER_TOO_SMALL
) {
802 Desc
= "Warning Buffer Too Small";
807 // If we found a match, copy the message to the user's buffer. Otherwise
808 // sprint the hex status code to their buffer.
811 Size
= ASPrint (Buffer
, BufferSize
, "%a", Desc
);
813 Size
= ASPrint (Buffer
, BufferSize
, "%X", Status
);