]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
This checkin addresses the compatibility issue of passing arguments of type VA_LIST...
[mirror_edk2.git] / MdeModulePkg / Library / DxePrintLibPrint2Protocol / PrintLib.c
index 3923f956cb4ea67853e30e4d41f3d0658749f92b..d22d4d5566488f5f6636085b5501bc7119eab60d 100644 (file)
@@ -18,7 +18,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include <Uefi.h>\r
+\r
 #include <Protocol/Print2.h>\r
+\r
+#include <Library/PrintLib.h>\r
+\r
+#include <Library/BaseLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
@@ -57,6 +62,166 @@ PrintLibConstructor (
 }\r
 \r
 \r
+/**\r
+  Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated \r
+  format string.\r
+\r
+  @param  AsciiFormat     TRUE if Format is an ASCII string.  FALSE if Format is a Unicode string.\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
+  @param  Size            The size, in bytes, of the BaseListMarker buffer.\r
+\r
+  @return The number of bytes in BaseListMarker.  0 if BaseListMarker is too small.\r
+\r
+**/\r
+BOOLEAN\r
+DxePrintLibPrint2ProtocolVaListToBaseList (\r
+  IN  BOOLEAN      AsciiFormat,\r
+  IN  CONST CHAR8  *Format,\r
+  IN  VA_LIST      VaListMarker,\r
+  OUT BASE_LIST    BaseListMarker,\r
+  IN  UINTN        Size\r
+  )\r
+{\r
+  BASE_LIST  BaseListStart;\r
+  UINTN      BytesPerFormatCharacter;\r
+  UINTN      FormatMask;\r
+  UINTN      FormatCharacter;\r
+  BOOLEAN    Long;\r
+  BOOLEAN    Done;\r
+\r
+  ASSERT (Format         != NULL);\r
+  ASSERT (VaListMarker   != NULL);\r
+  ASSERT (BaseListMarker != NULL);\r
+\r
+  BaseListStart = BaseListMarker;\r
+\r
+  if (AsciiFormat) {\r
+    ASSERT (AsciiStrSize (Format) != 0);\r
+    BytesPerFormatCharacter = 1;\r
+    FormatMask = 0xff;\r
+  } else {\r
+    ASSERT (StrSize ((CHAR16 *) Format) != 0);\r
+    BytesPerFormatCharacter = 2;\r
+    FormatMask = 0xffff;\r
+  }\r
+\r
+  //\r
+  // Get the first character from the format string\r
+  //\r
+  FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+\r
+  while (FormatCharacter != 0) {\r
+    if (FormatCharacter == '%') {\r
+      Long = FALSE;\r
+\r
+      //\r
+      // Parse Flags and Width\r
+      //\r
+      for (Done = FALSE; !Done; ) {\r
+        //\r
+        // Get the next character from the format string\r
+        //\r
+        Format += BytesPerFormatCharacter;\r
+\r
+        //\r
+        // Get the next character from the format string\r
+        //\r
+        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+\r
+        switch (FormatCharacter) {\r
+        case '.': \r
+        case '-': \r
+        case '+': \r
+        case ' ': \r
+        case ',': \r
+        case '0':\r
+        case '1':\r
+        case '2':\r
+        case '3':\r
+        case '4':\r
+        case '5':\r
+        case '6':\r
+        case '7':\r
+        case '8':\r
+        case '9':\r
+          break;\r
+        case 'L':\r
+        case 'l': \r
+          Long = TRUE;\r
+          break;\r
+        case '*':\r
+          BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+          break;\r
+        case '\0':\r
+          //\r
+          // Make no output if Format string terminates unexpectedly when\r
+          // looking up for flag, width, precision and type. \r
+          //\r
+          Format -= BytesPerFormatCharacter;\r
+          //\r
+          // break skipped on purpose.\r
+          //\r
+        default:\r
+          Done = TRUE;\r
+          break;\r
+        }\r
+      } \r
+        \r
+      //\r
+      // Handle each argument type\r
+      //\r
+      switch (FormatCharacter) {\r
+      case 'p':\r
+        if (sizeof (VOID *) > 4) {\r
+          Long = TRUE;\r
+        }\r
+      case 'X':\r
+      case 'x':\r
+      case 'd':\r
+        if (Long) {\r
+          BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);\r
+        } else {\r
+          BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);\r
+        }\r
+        break;\r
+      case 's':\r
+      case 'S':\r
+      case 'a':\r
+      case 'g':\r
+      case 't':\r
+        BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);\r
+        break;\r
+      case 'c':\r
+        BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+        break;\r
+      case 'r':\r
+        BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS);\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // If BASE_LIST is larger than Size, then return FALSE\r
+    //\r
+    if ((UINTN)((UINT8 *)BaseListMarker - (UINT8 *)BaseListStart) > Size) {\r
+      return FALSE;\r
+    }\r
+\r
+    //\r
+    // Get the next character from the format string\r
+    //\r
+    Format += BytesPerFormatCharacter;\r
+\r
+    //\r
+    // Get the next character from the format string\r
+    //\r
+    FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
 /**\r
   Produces a Null-terminated Unicode string in an output buffer based on \r
   a Null-terminated Unicode format string and a VA_LIST argument list\r
@@ -100,7 +265,63 @@ UnicodeVSPrint (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  return mPrint2Protocol->UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  UINT8  BaseListMarker[256];\r
+\r
+  DxePrintLibPrint2ProtocolVaListToBaseList (\r
+    FALSE, \r
+    (CHAR8 *)FormatString, \r
+    Marker, \r
+    (BASE_LIST)BaseListMarker, \r
+    sizeof (BaseListMarker) - 8\r
+    );\r
+\r
+  return UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
+}\r
+\r
+/**\r
+  Produces a Null-terminated Unicode string in an output buffer based on \r
+  a Null-terminated Unicode format string and a BASE_LIST argument list\r
+  \r
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
+  and BufferSize.  \r
+  The Unicode string is produced by parsing the format string specified by FormatString.  \r
+  Arguments are pulled from the variable argument list specified by Marker based on the \r
+  contents of the format string.  \r
+  The number of Unicode characters in the produced output buffer is returned not including\r
+  the Null-terminator.\r
+  If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
+\r
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
+  If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
+  If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
+  ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated \r
+                          Unicode string.\r
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.\r
+  @param  FormatString    Null-terminated Unicode format string.\r
+  @param  Marker          BASE_LIST marker for the variable argument list.\r
+  \r
+  @return The number of Unicode characters in the produced output buffer not including the\r
+          Null-terminator.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnicodeBSPrint (\r
+  OUT CHAR16        *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  IN  BASE_LIST     Marker\r
+  )\r
+{\r
+  return mPrint2Protocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -194,7 +415,62 @@ UnicodeVSPrintAsciiFormat (
   IN  VA_LIST      Marker\r
   )\r
 {\r
-  return mPrint2Protocol->UnicodeSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  UINT8  BaseListMarker[256];\r
+\r
+  DxePrintLibPrint2ProtocolVaListToBaseList (\r
+    TRUE, \r
+    FormatString, \r
+    Marker, \r
+    (BASE_LIST)BaseListMarker, \r
+    sizeof (BaseListMarker) - 8\r
+    );\r
+\r
+  return UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
+}\r
+\r
+/**\r
+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
+  ASCII format string and a BASE_LIST argument list\r
+  \r
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
+  and BufferSize.\r
+  The Unicode string is produced by parsing the format string specified by FormatString.\r
+  Arguments are pulled from the variable argument list specified by Marker based on the \r
+  contents of the format string.\r
+  The number of Unicode characters in the produced output buffer is returned not including\r
+  the Null-terminator.\r
+  If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
+\r
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
+  If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
+  ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated \r
+                          Unicode string.\r
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.\r
+  @param  FormatString    Null-terminated Unicode format string.\r
+  @param  Marker          BASE_LIST marker for the variable argument list.\r
+  \r
+  @return The number of Unicode characters in the produced output buffer not including the\r
+          Null-terminator.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnicodeBSPrintAsciiFormat (\r
+  OUT CHAR16       *StartOfBuffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  CONST CHAR8  *FormatString,\r
+  IN  BASE_LIST    Marker\r
+  )\r
+{\r
+  return mPrint2Protocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -340,7 +616,61 @@ AsciiVSPrint (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  return mPrint2Protocol->AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  UINT8  BaseListMarker[256];\r
+\r
+  DxePrintLibPrint2ProtocolVaListToBaseList (\r
+    TRUE, \r
+    FormatString, \r
+    Marker, \r
+    (BASE_LIST)BaseListMarker, \r
+    sizeof (BaseListMarker) - 8\r
+    );\r
+\r
+  return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
+}\r
+\r
+/**\r
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
+  ASCII format string and a BASE_LIST argument list.\r
+  \r
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
+  and BufferSize.\r
+  The ASCII string is produced by parsing the format string specified by FormatString.\r
+  Arguments are pulled from the variable argument list specified by Marker based on \r
+  the contents of the format string.\r
+  The number of ASCII characters in the produced output buffer is returned not including\r
+  the Null-terminator.\r
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
+\r
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
+  If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
+  ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated \r
+                          ASCII string.\r
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.\r
+  @param  FormatString    Null-terminated Unicode format string.\r
+  @param  Marker          BASE_LIST marker for the variable argument list.\r
+  \r
+  @return The number of ASCII characters in the produced output buffer not including the\r
+          Null-terminator.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiBSPrint (\r
+  OUT CHAR8         *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR8   *FormatString,\r
+  IN  BASE_LIST     Marker\r
+  )\r
+{\r
+  return mPrint2Protocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -433,7 +763,62 @@ AsciiVSPrintUnicodeFormat (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  return mPrint2Protocol->AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  UINT8  BaseListMarker[256];\r
+\r
+  DxePrintLibPrint2ProtocolVaListToBaseList (\r
+    FALSE, \r
+    (CHAR8 *)FormatString, \r
+    Marker, \r
+    (BASE_LIST)BaseListMarker, \r
+    sizeof (BaseListMarker) - 8\r
+    );\r
+\r
+  return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
+}\r
+\r
+/**\r
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
+  ASCII format string and a BASE_LIST argument list.\r
+  \r
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
+  and BufferSize.\r
+  The ASCII string is produced by parsing the format string specified by FormatString.\r
+  Arguments are pulled from the variable argument list specified by Marker based on \r
+  the contents of the format string.\r
+  The number of ASCII characters in the produced output buffer is returned not including\r
+  the Null-terminator.\r
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
+\r
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
+  If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
+  If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
+  ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated \r
+                          ASCII string.\r
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.\r
+  @param  FormatString    Null-terminated Unicode format string.\r
+  @param  Marker          BASE_LIST marker for the variable argument list.\r
+  \r
+  @return The number of ASCII characters in the produced output buffer not including the\r
+          Null-terminator.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiBSPrintUnicodeFormat (\r
+  OUT CHAR8         *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  IN  BASE_LIST     Marker\r
+  )\r
+{\r
+  return mPrint2Protocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r