X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdePkg%2FLibrary%2FBasePrintLib%2FPrintLibInternal.c;h=ef006bbd00619e31239ce0bd53498ad18c44e05c;hp=05e3ed501dccfbfa5779292190efe688e59300a6;hb=40f2c454343be84ab3bacf9955cc8d7842c70b5c;hpb=d6039b1d6e83345e7354029ce104f87e304a5a5c diff --git a/MdePkg/Library/BasePrintLib/PrintLibInternal.c b/MdePkg/Library/BasePrintLib/PrintLibInternal.c index 05e3ed501d..ef006bbd00 100644 --- a/MdePkg/Library/BasePrintLib/PrintLibInternal.c +++ b/MdePkg/Library/BasePrintLib/PrintLibInternal.c @@ -61,6 +61,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mStatusString[] = { @param EndBuffer The end of the input Buffer. No characters will be placed after that. @param Length Count of character to be placed into Buffer. + (Negative value indicates no buffer fill.) @param Character Character to be placed into Buffer. @param Increment Character increment in Buffer. @@ -77,58 +78,52 @@ BasePrintLibFillBuffer ( ) { INTN Index; - if(Increment != 1) { - for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) { - *Buffer = (CHAR8) Character; - *(Buffer + 1) = (CHAR8) (Character >> 8); - } - Buffer += Increment; - } else { - for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) { - *Buffer = (CHAR8) Character; + + for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) { + *Buffer = (CHAR8) Character; + if (Increment != 1) { + *(Buffer + 1) = (CHAR8)(Character >> 8); } Buffer += Increment; } + return Buffer; } /** - Internal function that convert a decimal number to a string in Buffer. + Internal function that convert a number to a string in Buffer. - Print worker function that convert a decimal number to a string in Buffer. + Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer. - @param Buffer Location to place the Unicode or ASCII string of Value. - @param Value Value to convert to a Decimal or Hexidecimal string in Buffer. + @param Buffer Location to place the ASCII string of Value. + @param Value Value to convert to a Decimal or Hexadecimal string in Buffer. @param Radix Radix of the value - @return Number of characters printed. + @return A pointer to the end of buffer filled with ASCII string. **/ -UINTN +CHAR8 * BasePrintLibValueToString ( IN OUT CHAR8 *Buffer, IN INT64 Value, IN UINTN Radix ) { - UINTN Digits; UINT32 Remainder; // // Loop to convert one digit at a time in reverse order // - *(Buffer++) = 0; - Digits = 0; + *Buffer = 0; do { Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); - *(Buffer++) = mHexStr[Remainder]; - Digits++; + *(++Buffer) = mHexStr[Remainder]; } while (Value != 0); // - // the length of Buffer string converted from Value + // Return pointer of the end of filled buffer. // - return Digits; + return Buffer; } /** @@ -181,6 +176,7 @@ BasePrintLibConvertValueToString ( CHAR8 *OriginalBuffer; CHAR8 *EndBuffer; CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; + CHAR8 *ValueBufferPtr; UINTN Count; UINTN Digits; UINTN Index; @@ -199,7 +195,7 @@ BasePrintLibConvertValueToString ( // // If both COMMA_TYPE and HEX_RADIX are set, then ASSERT () // - ASSERT (((Flags & COMMA_TYPE) != 0 && (Flags & RADIX_HEX) != 0) == FALSE); + ASSERT (((Flags & COMMA_TYPE) == 0) || ((Flags & RADIX_HEX) == 0)); OriginalBuffer = Buffer; @@ -233,7 +229,8 @@ BasePrintLibConvertValueToString ( // Count the length of the value string. // Radix = ((Flags & RADIX_HEX) == 0)? 10 : 16; - Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); + ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, Value, Radix); + Count = ValueBufferPtr - ValueBuffer; // // Append Zero @@ -250,7 +247,7 @@ BasePrintLibConvertValueToString ( Digits = 3 - Digits; } for (Index = 0; Index < Count; Index++) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ValueBuffer[Count - Index], Increment); + Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, *ValueBufferPtr--, Increment); if ((Flags & COMMA_TYPE) != 0) { Digits++; if (Digits == 3) { @@ -275,55 +272,57 @@ BasePrintLibConvertValueToString ( based on a Null-terminated format string and a VA_LIST argument list. VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this rountine allows the nesting of Vararg routines. Thus + VA_LIST is used this routine allows the nesting of Vararg routines. Thus this is the main print working routine. - @param Buffer Character buffer to print the results of the parsing - of Format into. - @param BufferSize Maximum number of characters to put into buffer. - @param Flags Intial flags value. - Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. - @param Format Null-terminated format string. - @param Marker Vararg list consumed by processing Format. + @param Buffer Character buffer to print the results of the parsing + of Format into. + @param BufferSize Maximum number of characters to put into buffer. + @param Flags Initial flags value. + Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. + @param Format Null-terminated format string. + @param VaListMarker VA_LIST style variable argument list consumed by processing Format. + @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format. @return Number of characters printed not including the Null-terminator. **/ UINTN -BasePrintLibVSPrint ( +BasePrintLibSPrintMarker ( OUT CHAR8 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN CONST CHAR8 *Format, - IN VA_LIST Marker + IN VA_LIST VaListMarker, OPTIONAL + IN BASE_LIST BaseListMarker OPTIONAL ) { - CHAR8 *OriginalBuffer; - CHAR8 *EndBuffer; - CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; - UINTN BytesPerOutputCharacter; - UINTN BytesPerFormatCharacter; - UINTN FormatMask; - UINTN FormatCharacter; - UINTN Width; - UINTN Precision; - INT64 Value; - CONST CHAR8 *ArgumentString; - UINTN Character; - GUID *TmpGuid; - TIME *TmpTime; - UINTN Count; - UINTN ArgumentMask; - INTN BytesPerArgumentCharacter; - UINTN ArgumentCharacter; - BOOLEAN Done; - UINTN Index; - CHAR8 Prefix; - BOOLEAN ZeroPad; - BOOLEAN Comma; - UINTN Digits; - UINTN Radix; - RETURN_STATUS Status; + CHAR8 *OriginalBuffer; + CHAR8 *EndBuffer; + CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; + UINTN BytesPerOutputCharacter; + UINTN BytesPerFormatCharacter; + UINTN FormatMask; + UINTN FormatCharacter; + UINTN Width; + UINTN Precision; + INT64 Value; + CONST CHAR8 *ArgumentString; + UINTN Character; + GUID *TmpGuid; + TIME *TmpTime; + UINTN Count; + UINTN ArgumentMask; + INTN BytesPerArgumentCharacter; + UINTN ArgumentCharacter; + BOOLEAN Done; + UINTN Index; + CHAR8 Prefix; + BOOLEAN ZeroPad; + BOOLEAN Comma; + UINTN Digits; + UINTN Radix; + RETURN_STATUS Status; if (BufferSize == 0) { return 0; @@ -341,6 +340,7 @@ BasePrintLibVSPrint ( // BufferSize--; OriginalBuffer = Buffer; + // // Set the tag for the end of the input Buffer. // @@ -364,8 +364,6 @@ BasePrintLibVSPrint ( FormatMask = 0xff; } - - // // Get the first character from the format string // @@ -422,9 +420,17 @@ BasePrintLibVSPrint ( case '*': if ((Flags & PRECISION) == 0) { Flags |= PAD_TO_WIDTH; - Width = VA_ARG (Marker, UINTN); + if (BaseListMarker == NULL) { + Width = VA_ARG (VaListMarker, UINTN); + } else { + Width = BASE_ARG (BaseListMarker, UINTN); + } } else { - Precision = VA_ARG (Marker, UINTN); + if (BaseListMarker == NULL) { + Precision = VA_ARG (VaListMarker, UINTN); + } else { + Precision = BASE_ARG (BaseListMarker, UINTN); + } } break; case '0': @@ -494,9 +500,25 @@ BasePrintLibVSPrint ( // case 'd': if ((Flags & LONG_TYPE) == 0) { - Value = (VA_ARG (Marker, int)); + // + // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int". + // This assumption is made so the format string definition is compatible with the ANSI C + // Specification for formatted strings. It is recommended that the Base Types be used + // everywhere, but in this one case, compliance with ANSI C is more important, and + // provides an implementation that is compatible with that largest possible set of CPU + // architectures. This is why the type "int" is used in this one case. + // + if (BaseListMarker == NULL) { + Value = VA_ARG (VaListMarker, int); + } else { + Value = BASE_ARG (BaseListMarker, int); + } } else { - Value = VA_ARG (Marker, INT64); + if (BaseListMarker == NULL) { + Value = VA_ARG (VaListMarker, INT64); + } else { + Value = BASE_ARG (BaseListMarker, INT64); + } } if ((Flags & PREFIX_BLANK) != 0) { Prefix = ' '; @@ -522,13 +544,21 @@ BasePrintLibVSPrint ( Radix = 16; Comma = FALSE; if ((Flags & LONG_TYPE) == 0 && Value < 0) { + // + // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int". + // This assumption is made so the format string definition is compatible with the ANSI C + // Specification for formatted strings. It is recommended that the Base Types be used + // everywhere, but in this one case, compliance with ANSI C is more important, and + // provides an implementation that is compatible with that largest possible set of CPU + // architectures. This is why the type "unsigned int" is used in this one case. + // Value = (unsigned int)Value; } } // // Convert Value to a reversed string // - Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); + Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer; if (Value == 0 && Precision == 0) { Count = 0; } @@ -565,7 +595,11 @@ BasePrintLibVSPrint ( // break skipped on purpose // case 'a': - ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *); + if (BaseListMarker == NULL) { + ArgumentString = VA_ARG (VaListMarker, CHAR8 *); + } else { + ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *); + } if (ArgumentString == NULL) { Flags &= (~ARGUMENT_UNICODE); ArgumentString = ""; @@ -579,13 +613,21 @@ BasePrintLibVSPrint ( break; case 'c': - Character = VA_ARG (Marker, UINTN) & 0xffff; + if (BaseListMarker == NULL) { + Character = VA_ARG (VaListMarker, UINTN) & 0xffff; + } else { + Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff; + } ArgumentString = (CHAR8 *)&Character; Flags |= ARGUMENT_UNICODE; break; case 'g': - TmpGuid = VA_ARG (Marker, GUID *); + if (BaseListMarker == NULL) { + TmpGuid = VA_ARG (VaListMarker, GUID *); + } else { + TmpGuid = BASE_ARG (BaseListMarker, GUID *); + } if (TmpGuid == NULL) { ArgumentString = ""; } else { @@ -611,7 +653,11 @@ BasePrintLibVSPrint ( break; case 't': - TmpTime = VA_ARG (Marker, TIME *); + if (BaseListMarker == NULL) { + TmpTime = VA_ARG (VaListMarker, TIME *); + } else { + TmpTime = BASE_ARG (BaseListMarker, TIME *); + } if (TmpTime == NULL) { ArgumentString = ""; } else { @@ -631,7 +677,11 @@ BasePrintLibVSPrint ( break; case 'r': - Status = VA_ARG (Marker, RETURN_STATUS); + if (BaseListMarker == NULL) { + Status = VA_ARG (VaListMarker, RETURN_STATUS); + } else { + Status = BASE_ARG (BaseListMarker, RETURN_STATUS); + } ArgumentString = ValueBuffer; if (RETURN_ERROR (Status)) { // @@ -795,14 +845,14 @@ BasePrintLibVSPrint ( based on a Null-terminated format string and variable argument list. VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this rountine allows the nesting of Vararg routines. Thus + VA_LIST is used this routine allows the nesting of Vararg routines. Thus this is the main print working routine @param StartOfBuffer Character buffer to print the results of the parsing of Format into. @param BufferSize Maximum number of characters to put into buffer. Zero means no limit. - @param Flags Intial flags value. + @param Flags Initial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set @param FormatString Null-terminated format string. @param ... The variable argument list. @@ -822,5 +872,5 @@ BasePrintLibSPrint ( VA_LIST Marker; VA_START (Marker, FormatString); - return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker); + return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL); }