]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePrintLib/PrintLibInternal.c
* Modify various PCI register settings for OVMF.
[mirror_edk2.git] / MdePkg / Library / BasePrintLib / PrintLibInternal.c
index 1c42baecfcf1ea159771b3ce100dd6cb9cc05083..ef006bbd00619e31239ce0bd53498ad18c44e05c 100644 (file)
@@ -91,42 +91,39 @@ BasePrintLibFillBuffer (
 }\r
 \r
 /**\r
-  Internal function that convert a decimal number to a string in Buffer.\r
+  Internal function that convert a number to a string in Buffer.\r
 \r
-  Print worker function that convert a decimal number to a string in Buffer.\r
+  Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.\r
 \r
-  @param  Buffer    Location to place the Unicode or ASCII string of Value.\r
+  @param  Buffer    Location to place the ASCII string of Value.\r
   @param  Value     Value to convert to a Decimal or Hexadecimal string in Buffer.\r
   @param  Radix     Radix of the value\r
 \r
-  @return Number of characters printed.\r
+  @return A pointer to the end of buffer filled with ASCII string.\r
 \r
 **/\r
-UINTN\r
+CHAR8 *\r
 BasePrintLibValueToString (\r
   IN OUT CHAR8  *Buffer, \r
   IN INT64      Value, \r
   IN UINTN      Radix\r
   )\r
 {\r
-  UINTN   Digits;\r
   UINT32  Remainder;\r
 \r
   //\r
   // Loop to convert one digit at a time in reverse order\r
   //\r
-  *(Buffer++) = 0;\r
-  Digits = 0;\r
+  *Buffer = 0;\r
   do {\r
     Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);\r
-    *(Buffer++) = mHexStr[Remainder];\r
-    Digits++;\r
+    *(++Buffer) = mHexStr[Remainder];\r
   } while (Value != 0);\r
 \r
   //\r
-  // the length of Buffer string converted from Value\r
+  // Return pointer of the end of filled buffer.\r
   //\r
-  return Digits;\r
+  return Buffer;\r
 }\r
 \r
 /**\r
@@ -179,6 +176,7 @@ BasePrintLibConvertValueToString (
   CHAR8  *OriginalBuffer;\r
   CHAR8  *EndBuffer;\r
   CHAR8  ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
+  CHAR8  *ValueBufferPtr;\r
   UINTN  Count;\r
   UINTN  Digits;\r
   UINTN  Index;\r
@@ -197,7 +195,7 @@ BasePrintLibConvertValueToString (
   //\r
   // If both COMMA_TYPE and HEX_RADIX are set, then ASSERT ()\r
   //\r
-  ASSERT (((Flags & COMMA_TYPE) != 0 && (Flags & RADIX_HEX) != 0) == FALSE);\r
+  ASSERT (((Flags & COMMA_TYPE) == 0) || ((Flags & RADIX_HEX) == 0));\r
 \r
   OriginalBuffer = Buffer;\r
   \r
@@ -231,7 +229,8 @@ BasePrintLibConvertValueToString (
   // Count the length of the value string.\r
   //\r
   Radix = ((Flags & RADIX_HEX) == 0)? 10 : 16;\r
-  Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+  ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+  Count = ValueBufferPtr - ValueBuffer;\r
   \r
   //\r
   // Append Zero\r
@@ -248,7 +247,7 @@ BasePrintLibConvertValueToString (
     Digits = 3 - Digits;\r
   }\r
   for (Index = 0; Index < Count; Index++) {\r
-    Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ValueBuffer[Count - Index], Increment);\r
+    Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, *ValueBufferPtr--, Increment);\r
     if ((Flags & COMMA_TYPE) != 0) {\r
       Digits++;\r
       if (Digits == 3) {\r
@@ -273,55 +272,57 @@ BasePrintLibConvertValueToString (
   based on a Null-terminated format string and a VA_LIST argument list.\r
 \r
   VSPrint function to process format and place the results in Buffer. Since a \r
-  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
   this is the main print working routine.\r
 \r
-  @param  Buffer      Character buffer to print the results of the parsing\r
-                      of Format into.\r
-  @param  BufferSize  Maximum number of characters to put into buffer.\r
-  @param  Flags       Intial flags value.\r
-                      Can only have FORMAT_UNICODE and OUTPUT_UNICODE set.\r
-  @param  Format      Null-terminated format string.\r
-  @param  Marker      Vararg list consumed by processing Format.\r
+  @param  Buffer          Character buffer to print the results of the parsing\r
+                          of Format into.\r
+  @param  BufferSize      Maximum number of characters to put into buffer.\r
+  @param  Flags           Initial flags value.\r
+                          Can only have FORMAT_UNICODE and OUTPUT_UNICODE set.\r
+  @param  Format          Null-terminated format string.\r
+  @param  VaListMarker    VA_LIST style variable argument list consumed by processing Format.\r
+  @param  BaseListMarker  BASE_LIST style variable argument list consumed by processing Format.\r
 \r
   @return Number of characters printed not including the Null-terminator.\r
 \r
 **/\r
 UINTN\r
-BasePrintLibVSPrint (\r
+BasePrintLibSPrintMarker (\r
   OUT CHAR8        *Buffer,\r
   IN  UINTN        BufferSize,\r
   IN  UINTN        Flags,\r
   IN  CONST CHAR8  *Format,\r
-  IN  VA_LIST      Marker\r
+  IN  VA_LIST      VaListMarker,   OPTIONAL\r
+  IN  BASE_LIST    BaseListMarker  OPTIONAL\r
   )\r
 {\r
-  CHAR8           *OriginalBuffer;\r
-  CHAR8           *EndBuffer;\r
-  CHAR8           ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
-  UINTN           BytesPerOutputCharacter;\r
-  UINTN           BytesPerFormatCharacter;\r
-  UINTN           FormatMask;\r
-  UINTN           FormatCharacter;\r
-  UINTN           Width;\r
-  UINTN           Precision;\r
-  INT64           Value;\r
-  CONST CHAR8     *ArgumentString;\r
-  UINTN           Character;\r
-  GUID            *TmpGuid;\r
-  TIME            *TmpTime;\r
-  UINTN           Count;\r
-  UINTN           ArgumentMask;\r
-  INTN            BytesPerArgumentCharacter;\r
-  UINTN           ArgumentCharacter;\r
-  BOOLEAN         Done;\r
-  UINTN           Index;\r
-  CHAR8           Prefix;\r
-  BOOLEAN         ZeroPad;\r
-  BOOLEAN         Comma;\r
-  UINTN           Digits;\r
-  UINTN           Radix;\r
-  RETURN_STATUS   Status;\r
+  CHAR8             *OriginalBuffer;\r
+  CHAR8             *EndBuffer;\r
+  CHAR8             ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
+  UINTN             BytesPerOutputCharacter;\r
+  UINTN             BytesPerFormatCharacter;\r
+  UINTN             FormatMask;\r
+  UINTN             FormatCharacter;\r
+  UINTN             Width;\r
+  UINTN             Precision;\r
+  INT64             Value;\r
+  CONST CHAR8       *ArgumentString;\r
+  UINTN             Character;\r
+  GUID              *TmpGuid;\r
+  TIME              *TmpTime;\r
+  UINTN             Count;\r
+  UINTN             ArgumentMask;\r
+  INTN              BytesPerArgumentCharacter;\r
+  UINTN             ArgumentCharacter;\r
+  BOOLEAN           Done;\r
+  UINTN             Index;\r
+  CHAR8             Prefix;\r
+  BOOLEAN           ZeroPad;\r
+  BOOLEAN           Comma;\r
+  UINTN             Digits;\r
+  UINTN             Radix;\r
+  RETURN_STATUS     Status;\r
 \r
   if (BufferSize == 0) {\r
     return 0;\r
@@ -339,6 +340,7 @@ BasePrintLibVSPrint (
   //\r
   BufferSize--;\r
   OriginalBuffer = Buffer;\r
+\r
   //\r
   // Set the tag for the end of the input Buffer.\r
   //\r
@@ -362,8 +364,6 @@ BasePrintLibVSPrint (
     FormatMask = 0xff;\r
   }\r
 \r
-\r
-\r
   //\r
   // Get the first character from the format string\r
   //\r
@@ -420,9 +420,17 @@ BasePrintLibVSPrint (
         case '*':\r
           if ((Flags & PRECISION) == 0) {\r
             Flags |= PAD_TO_WIDTH;\r
-            Width = VA_ARG (Marker, UINTN);\r
+            if (BaseListMarker == NULL) {\r
+              Width = VA_ARG (VaListMarker, UINTN);\r
+            } else {\r
+              Width = BASE_ARG (BaseListMarker, UINTN);\r
+            }\r
           } else {\r
-            Precision = VA_ARG (Marker, UINTN);\r
+            if (BaseListMarker == NULL) {\r
+              Precision = VA_ARG (VaListMarker, UINTN);\r
+            } else {\r
+              Precision = BASE_ARG (BaseListMarker, UINTN);\r
+            }\r
           }\r
           break;\r
         case '0':\r
@@ -492,9 +500,25 @@ BasePrintLibVSPrint (
         //\r
       case 'd':\r
         if ((Flags & LONG_TYPE) == 0) {\r
-          Value = (VA_ARG (Marker, int));\r
+          //\r
+          // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
+          // This assumption is made so the format string definition is compatible with the ANSI C\r
+          // Specification for formatted strings.  It is recommended that the Base Types be used \r
+          // everywhere, but in this one case, compliance with ANSI C is more important, and \r
+          // provides an implementation that is compatible with that largest possible set of CPU \r
+          // architectures.  This is why the type "int" is used in this one case.\r
+          //\r
+          if (BaseListMarker == NULL) {\r
+            Value = VA_ARG (VaListMarker, int);\r
+          } else {\r
+            Value = BASE_ARG (BaseListMarker, int);\r
+          }\r
         } else {\r
-          Value = VA_ARG (Marker, INT64);\r
+          if (BaseListMarker == NULL) {\r
+            Value = VA_ARG (VaListMarker, INT64);\r
+          } else {\r
+            Value = BASE_ARG (BaseListMarker, INT64);\r
+          }\r
         }\r
         if ((Flags & PREFIX_BLANK) != 0) {\r
           Prefix = ' ';\r
@@ -520,13 +544,21 @@ BasePrintLibVSPrint (
           Radix = 16;\r
           Comma = FALSE;\r
           if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
+            //\r
+            // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
+            // This assumption is made so the format string definition is compatible with the ANSI C\r
+            // Specification for formatted strings.  It is recommended that the Base Types be used \r
+            // everywhere, but in this one case, compliance with ANSI C is more important, and \r
+            // provides an implementation that is compatible with that largest possible set of CPU \r
+            // architectures.  This is why the type "unsigned int" is used in this one case.\r
+            //\r
             Value = (unsigned int)Value;\r
           }\r
         }\r
         //\r
         // Convert Value to a reversed string\r
         //\r
-        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;\r
         if (Value == 0 && Precision == 0) {\r
           Count = 0;\r
         }\r
@@ -563,7 +595,11 @@ BasePrintLibVSPrint (
         // break skipped on purpose\r
         //\r
       case 'a':\r
-        ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);\r
+        if (BaseListMarker == NULL) {\r
+          ArgumentString = VA_ARG (VaListMarker, CHAR8 *);\r
+        } else {\r
+          ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);\r
+        }\r
         if (ArgumentString == NULL) {\r
           Flags &= (~ARGUMENT_UNICODE);\r
           ArgumentString = "<null string>";\r
@@ -577,13 +613,21 @@ BasePrintLibVSPrint (
         break;\r
 \r
       case 'c':\r
-        Character = VA_ARG (Marker, UINTN) & 0xffff;\r
+        if (BaseListMarker == NULL) {\r
+          Character = VA_ARG (VaListMarker, UINTN) & 0xffff;\r
+        } else {\r
+          Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;\r
+        }\r
         ArgumentString = (CHAR8 *)&Character;\r
         Flags |= ARGUMENT_UNICODE;\r
         break;\r
 \r
       case 'g':\r
-        TmpGuid = VA_ARG (Marker, GUID *);\r
+        if (BaseListMarker == NULL) {\r
+          TmpGuid = VA_ARG (VaListMarker, GUID *);\r
+        } else {\r
+          TmpGuid = BASE_ARG (BaseListMarker, GUID *);\r
+        }\r
         if (TmpGuid == NULL) {\r
           ArgumentString = "<null guid>";\r
         } else {\r
@@ -609,7 +653,11 @@ BasePrintLibVSPrint (
         break;\r
 \r
       case 't':\r
-        TmpTime = VA_ARG (Marker, TIME *); \r
+        if (BaseListMarker == NULL) {\r
+          TmpTime = VA_ARG (VaListMarker, TIME *); \r
+        } else {\r
+          TmpTime = BASE_ARG (BaseListMarker, TIME *); \r
+        }\r
         if (TmpTime == NULL) {\r
           ArgumentString = "<null time>";\r
         } else {\r
@@ -629,7 +677,11 @@ BasePrintLibVSPrint (
         break;\r
 \r
       case 'r':\r
-        Status = VA_ARG (Marker, RETURN_STATUS);\r
+        if (BaseListMarker == NULL) {\r
+          Status = VA_ARG (VaListMarker, RETURN_STATUS);\r
+        } else {\r
+          Status = BASE_ARG (BaseListMarker, RETURN_STATUS);\r
+        }\r
         ArgumentString = ValueBuffer;\r
         if (RETURN_ERROR (Status)) {\r
           //\r
@@ -793,14 +845,14 @@ BasePrintLibVSPrint (
   based on a Null-terminated format string and variable argument list.\r
 \r
   VSPrint function to process format and place the results in Buffer. Since a \r
-  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
   this is the main print working routine\r
 \r
   @param  StartOfBuffer Character buffer to print the results of the parsing\r
                         of Format into.\r
   @param  BufferSize    Maximum number of characters to put into buffer.\r
                         Zero means no limit.\r
-  @param  Flags         Intial flags value.\r
+  @param  Flags         Initial flags value.\r
                         Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
   @param  FormatString  Null-terminated format string.\r
   @param  ...           The variable argument list.\r
@@ -820,5 +872,5 @@ BasePrintLibSPrint (
   VA_LIST  Marker;\r
 \r
   VA_START (Marker, FormatString);\r
-  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);\r
+  return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);\r
 }\r