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
109 IN CONST CHAR8
*Format
,
116 ASPrint function to process format and place the results in Buffer.
120 Buffer - Ascii buffer to print the results of the parsing of Format into.
122 BufferSize - Maximum number of characters to put into buffer. Zero means no
125 Format - Ascii format string see file header for more details.
127 ... - Vararg list consumed by processing Format.
131 Number of characters printed.
138 VA_START(Marker
, Format
);
139 Return
= AvSPrint(Buffer
, BufferSize
, Format
, Marker
);
148 OUT CHAR8
*StartOfBuffer
,
150 IN CONST CHAR8
*FormatString
,
157 AvSPrint function to process format and place the results in Buffer. Since a
158 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
159 this is the main print working routine
163 StartOfBuffer - Ascii buffer to print the results of the parsing of Format into.
165 BufferSize - Maximum number of characters to put into buffer. Zero means
168 FormatString - Ascii format string see file header for more details.
170 Marker - Vararg list consumed by processing Format.
174 Number of characters printed.
178 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
193 // Process the format string. Stop if Buffer is over run.
195 Buffer
= StartOfBuffer
;
196 Format
= (CHAR8
*) FormatString
;
197 BufferLeft
= BufferSize
;
198 for (Index
= 0; (*Format
!= '\0') && (Index
< BufferSize
- 1); Format
++) {
199 if (*Format
!= '%') {
200 if ((*Format
== '\n') && (Index
< BufferSize
- 2)) {
202 // If carage return add line feed
204 Buffer
[Index
++] = '\r';
205 BufferLeft
-= sizeof (CHAR8
);
208 Buffer
[Index
++] = *Format
;
209 BufferLeft
-= sizeof (CHAR8
);
213 // Now it's time to parse what follows after %
217 for (Done
= FALSE
; !Done
; ) {
222 case '-': Flags
|= LEFT_JUSTIFY
; break;
223 case '+': Flags
|= PREFIX_SIGN
; break;
224 case ' ': Flags
|= PREFIX_BLANK
; break;
225 case ',': Flags
|= COMMA_TYPE
; break;
227 case 'l': Flags
|= LONG_TYPE
; break;
230 Width
= VA_ARG (Marker
, UINTN
);
234 Flags
|= PREFIX_ZERO
;
246 Count
= (Count
* 10) + *Format
- '0';
248 } while ((*Format
>= '0') && (*Format
<= '9'));
261 // Flag space, +, 0, L & l are invalid for type p.
263 Flags
&= ~(PREFIX_BLANK
| PREFIX_SIGN
| LONG_TYPE
);
264 if (sizeof (VOID
*) > 4) {
266 Value
= VA_ARG (Marker
, UINT64
);
268 Value
= VA_ARG (Marker
, UINTN
);
270 Flags
|= PREFIX_ZERO
;
272 ValueTomHexStr (TempBuffer
, Value
, Flags
, Width
);
273 AsciiStr
= TempBuffer
;
275 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
276 Buffer
[Index
++] = *AsciiStr
;
280 Flags
|= PREFIX_ZERO
;
281 Width
= sizeof (UINT64
) * 2;
284 // break skiped on purpose
287 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
288 Value
= VA_ARG (Marker
, UINT64
);
290 Value
= VA_ARG (Marker
, UINTN
);
293 ValueTomHexStr (TempBuffer
, Value
, Flags
, Width
);
294 AsciiStr
= TempBuffer
;
296 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
297 Buffer
[Index
++] = *AsciiStr
;
302 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
303 Value
= VA_ARG (Marker
, UINT64
);
305 Value
= (UINTN
) VA_ARG (Marker
, UINTN
);
308 ValueToString (TempBuffer
, Value
, Flags
, Width
);
309 AsciiStr
= TempBuffer
;
311 for (; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++) {
312 Buffer
[Index
++] = *AsciiStr
;
318 UnicodeStr
= (CHAR16
*) VA_ARG (Marker
, CHAR8
*);
319 if (UnicodeStr
== NULL
) {
320 UnicodeStr
= L
"<null string>";
323 for (Count
= 0; (*UnicodeStr
!= '\0') && (Index
< BufferSize
- 1); UnicodeStr
++, Count
++) {
324 Buffer
[Index
++] = (CHAR8
) *UnicodeStr
;
327 // Add padding if needed
329 for (; (Count
< Width
) && (Index
< BufferSize
- 1); Count
++) {
330 Buffer
[Index
++] = ' ';
336 AsciiStr
= (CHAR8
*) VA_ARG (Marker
, CHAR8
*);
337 if (AsciiStr
== NULL
) {
338 AsciiStr
= "<null string>";
341 for (Count
= 0; (*AsciiStr
!= '\0') && (Index
< BufferSize
- 1); AsciiStr
++, Count
++) {
342 Buffer
[Index
++] = *AsciiStr
;
345 // Add padding if needed
347 for (; (Count
< Width
) && (Index
< BufferSize
- 1); Count
++) {
348 Buffer
[Index
++] = ' ';
353 Buffer
[Index
++] = (CHAR8
) VA_ARG (Marker
, UINTN
);
357 TmpGUID
= VA_ARG (Marker
, EFI_GUID
*);
358 if (TmpGUID
!= NULL
) {
359 Index
+= GuidToString (
368 Index
+= TimeToString (
369 VA_ARG (Marker
, EFI_TIME
*),
376 Index
+= EfiStatusToString (
377 VA_ARG (Marker
, EFI_STATUS
),
384 Buffer
[Index
++] = *Format
;
389 // if the type is unknown print it to the screen
391 Buffer
[Index
++] = *Format
;
394 BufferLeft
= BufferSize
- Index
;
398 Buffer
[Index
++] = '\0';
400 return &Buffer
[Index
] - StartOfBuffer
;
405 static CHAR8 mHexStr
[] = { '0','1','2','3','4','5','6','7',
406 '8','9','A','B','C','D','E','F' };
411 IN OUT CHAR8
*Buffer
,
420 AvSPrint worker function that prints a Value as a hex number in Buffer
424 Buffer - Location to place ascii hex string of Value.
426 Value - Hex value to convert to a string in Buffer.
428 Flags - Flags to use in printing Hex string, see file header for details.
430 Width - Width of hex value.
434 Number of characters printed.
438 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
445 TempStr
= TempBuffer
;
449 // Count starts at one since we will null terminate. Each iteration of the
450 // loop picks off one nibble. Oh yea TempStr ends up backwards
454 *(TempStr
++) = mHexStr
[Value
& 0x0f];
455 Value
= RShiftU64 (Value
, 4);
457 } while (Value
!= 0);
459 if (Flags
& PREFIX_ZERO
) {
461 } else if (!(Flags
& LEFT_JUSTIFY
)) {
466 for (Index
= Count
; Index
< Width
; Index
++) {
467 *(TempStr
++) = Prefix
;
471 // Reverse temp string into Buffer.
473 if (Width
> 0 && (UINTN
) (TempStr
- TempBuffer
) > Width
) {
474 TempStr
= TempBuffer
+ Width
;
477 while (TempStr
!= TempBuffer
) {
478 *(BufferPtr
++) = *(--TempStr
);
489 IN OUT CHAR8
*Buffer
,
498 AvSPrint worker function that prints a Value as a decimal number in Buffer
502 Buffer - Location to place ascii decimal number string of Value.
504 Value - Decimal value to convert to a string in Buffer.
506 Flags - Flags to use in printing decimal string, see file header for details.
508 Width - Width of hex value.
512 Number of characters printed.
516 CHAR8 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
526 TempStr
= TempBuffer
;
537 Value
= (INT64
)DivU64x32 ((UINT64
)Value
, 10, &Remainder
);
538 *(TempStr
++) = (CHAR8
)(Remainder
+ '0');
541 if ((Flags
& COMMA_TYPE
) == COMMA_TYPE
) {
542 if (NumberCount
% 3 == 0 && Value
!= 0) {
547 } while (Value
!= 0);
550 *(BufferPtr
++) = '-';
555 // Reverse temp string into Buffer.
557 if (Width
> 0 && (UINTN
) (TempStr
- TempBuffer
) > Width
) {
558 TempStr
= TempBuffer
+ Width
;
561 while (TempStr
!= TempBuffer
) {
562 *(BufferPtr
++) = *(--TempStr
);
580 AvSPrint worker function that prints an EFI_GUID.
584 Guid - Pointer to GUID to print.
586 Buffer - Buffe to print Guid into.
588 BufferSize - Size of Buffer.
592 Number of characters printed.
601 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
605 (UINTN
)Guid
->Data4
[0],
606 (UINTN
)Guid
->Data4
[1],
607 (UINTN
)Guid
->Data4
[2],
608 (UINTN
)Guid
->Data4
[3],
609 (UINTN
)Guid
->Data4
[4],
610 (UINTN
)Guid
->Data4
[5],
611 (UINTN
)Guid
->Data4
[6],
612 (UINTN
)Guid
->Data4
[7]
616 // ASPrint will null terminate the string. The -1 skips the null
633 AvSPrint worker function that prints EFI_TIME.
637 Time - Pointer to EFI_TIME sturcture to print.
639 Buffer - Buffer to print Time into.
641 BufferSize - Size of Buffer.
645 Number of characters printed.
654 "%02d/%02d/%04d %02d:%02d",
663 // ASPrint will null terminate the string. The -1 skips the null
671 IN EFI_STATUS Status
,
679 AvSPrint worker function that prints EFI_STATUS as a string. If string is
680 not known a hex value will be printed.
684 Status - EFI_STATUS sturcture to print.
686 Buffer - Buffer to print EFI_STATUS message string into.
688 BufferSize - Size of Buffer.
692 Number of characters printed.
699 if (Status
== EFI_SUCCESS
) {
701 } else if (Status
== EFI_LOAD_ERROR
) {
703 } else if (Status
== EFI_INVALID_PARAMETER
) {
704 Desc
= "Invalid Parameter";
705 } else if (Status
== EFI_UNSUPPORTED
) {
706 Desc
= "Unsupported";
707 } else if (Status
== EFI_BAD_BUFFER_SIZE
) {
708 Desc
= "Bad Buffer Size";
709 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
710 Desc
= "Buffer Too Small";
711 } else if (Status
== EFI_NOT_READY
) {
713 } else if (Status
== EFI_DEVICE_ERROR
) {
714 Desc
= "Device Error";
715 } else if (Status
== EFI_WRITE_PROTECTED
) {
716 Desc
= "Write Protected";
717 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
718 Desc
= "Out of Resources";
719 } else if (Status
== EFI_VOLUME_CORRUPTED
) {
720 Desc
= "Volume Corrupt";
721 } else if (Status
== EFI_VOLUME_FULL
) {
722 Desc
= "Volume Full";
723 } else if (Status
== EFI_NO_MEDIA
) {
725 } else if (Status
== EFI_MEDIA_CHANGED
) {
726 Desc
= "Media changed";
727 } else if (Status
== EFI_NOT_FOUND
) {
729 } else if (Status
== EFI_ACCESS_DENIED
) {
730 Desc
= "Access Denied";
731 } else if (Status
== EFI_NO_RESPONSE
) {
732 Desc
= "No Response";
733 } else if (Status
== EFI_NO_MAPPING
) {
735 } else if (Status
== EFI_TIMEOUT
) {
737 } else if (Status
== EFI_NOT_STARTED
) {
738 Desc
= "Not started";
739 } else if (Status
== EFI_ALREADY_STARTED
) {
740 Desc
= "Already started";
741 } else if (Status
== EFI_ABORTED
) {
743 } else if (Status
== EFI_ICMP_ERROR
) {
745 } else if (Status
== EFI_TFTP_ERROR
) {
747 } else if (Status
== EFI_PROTOCOL_ERROR
) {
748 Desc
= "Protocol Error";
749 } else if (Status
== EFI_WARN_UNKNOWN_GLYPH
) {
750 Desc
= "Warning Unknown Glyph";
751 } else if (Status
== EFI_WARN_DELETE_FAILURE
) {
752 Desc
= "Warning Delete Failure";
753 } else if (Status
== EFI_WARN_WRITE_FAILURE
) {
754 Desc
= "Warning Write Failure";
755 } else if (Status
== EFI_WARN_BUFFER_TOO_SMALL
) {
756 Desc
= "Warning Buffer Too Small";
761 // If we found a match, copy the message to the user's buffer. Otherwise
762 // sprint the hex status code to their buffer.
765 Size
= ASPrint (Buffer
, BufferSize
, "%a", Desc
);
767 Size
= ASPrint (Buffer
, BufferSize
, "%X", Status
);