]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
MdePkg/BasePrintLib: Refine the SPrint functions
[mirror_edk2.git] / MdeModulePkg / Library / DxePrintLibPrint2Protocol / PrintLib.c
index e8a41f76cd1ee0d23072e64e8adc5e57dfeb766c..01378687fd58e7303c0c42bfc946eace70ed6cd9 100644 (file)
@@ -6,7 +6,7 @@
   protocol related to this implementation, not in the public spec. So, this \r
   library instance is only for this code base.\r
 \r
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -71,7 +71,8 @@ PrintLibConstructor (
   @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
+  @return TRUE   The VA_LIST has been converted to BASE_LIST.\r
+  @return FALSE  The VA_LIST has not been converted to BASE_LIST.\r
 \r
 **/\r
 BOOLEAN\r
@@ -177,6 +178,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
         }\r
       case 'X':\r
       case 'x':\r
+      case 'u':\r
       case 'd':\r
         if (Long) {\r
           BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);\r
@@ -204,6 +206,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
     // If BASE_LIST is larger than Size, then return FALSE\r
     //\r
     if ((UINTN)((UINT8 *)BaseListMarker - (UINT8 *)BaseListStart) > Size) {\r
+      DEBUG ((DEBUG_ERROR, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));\r
       return FALSE;\r
     }\r
 \r
@@ -263,15 +266,19 @@ UnicodeVSPrint (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  UINT64  BaseListMarker[256 / sizeof (UINT64)];\r
-\r
-  DxePrintLibPrint2ProtocolVaListToBaseList (\r
-    FALSE, \r
-    (CHAR8 *)FormatString, \r
-    Marker, \r
-    (BASE_LIST)BaseListMarker, \r
-    sizeof (BaseListMarker) - 8\r
-    );\r
+  UINT64   BaseListMarker[256 / sizeof (UINT64)];\r
+  BOOLEAN  Converted;\r
+\r
+  Converted = DxePrintLibPrint2ProtocolVaListToBaseList (\r
+                FALSE,\r
+                (CHAR8 *)FormatString,\r
+                Marker,\r
+                (BASE_LIST)BaseListMarker,\r
+                sizeof (BaseListMarker) - 8\r
+                );\r
+  if (!Converted) {\r
+    return 0;\r
+  }\r
 \r
   return UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
 }\r
@@ -416,15 +423,19 @@ UnicodeVSPrintAsciiFormat (
   IN  VA_LIST      Marker\r
   )\r
 {\r
-  UINT64  BaseListMarker[256 / sizeof (UINT64)];\r
-\r
-  DxePrintLibPrint2ProtocolVaListToBaseList (\r
-    TRUE, \r
-    FormatString, \r
-    Marker, \r
-    (BASE_LIST)BaseListMarker, \r
-    sizeof (BaseListMarker) - 8\r
-    );\r
+  UINT64   BaseListMarker[256 / sizeof (UINT64)];\r
+  BOOLEAN  Converted;\r
+\r
+  Converted = DxePrintLibPrint2ProtocolVaListToBaseList (\r
+                TRUE,\r
+                FormatString,\r
+                Marker,\r
+                (BASE_LIST)BaseListMarker,\r
+                sizeof (BaseListMarker) - 8\r
+                );\r
+  if (!Converted) {\r
+    return 0;\r
+  }\r
 \r
   return UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
 }\r
@@ -620,15 +631,19 @@ AsciiVSPrint (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  UINT64  BaseListMarker[256 / sizeof (UINT64)];\r
-\r
-  DxePrintLibPrint2ProtocolVaListToBaseList (\r
-    TRUE, \r
-    FormatString, \r
-    Marker, \r
-    (BASE_LIST)BaseListMarker, \r
-    sizeof (BaseListMarker) - 8\r
-    );\r
+  UINT64   BaseListMarker[256 / sizeof (UINT64)];\r
+  BOOLEAN  Converted;\r
+\r
+  Converted = DxePrintLibPrint2ProtocolVaListToBaseList (\r
+                TRUE,\r
+                FormatString,\r
+                Marker,\r
+                (BASE_LIST)BaseListMarker,\r
+                sizeof (BaseListMarker) - 8\r
+                );\r
+  if (!Converted) {\r
+    return 0;\r
+  }\r
 \r
   return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
 }\r
@@ -770,15 +785,19 @@ AsciiVSPrintUnicodeFormat (
   IN  VA_LIST       Marker\r
   )\r
 {\r
-  UINT64  BaseListMarker[256 / sizeof (UINT64)];\r
-\r
-  DxePrintLibPrint2ProtocolVaListToBaseList (\r
-    FALSE, \r
-    (CHAR8 *)FormatString, \r
-    Marker, \r
-    (BASE_LIST)BaseListMarker, \r
-    sizeof (BaseListMarker) - 8\r
-    );\r
+  UINT64   BaseListMarker[256 / sizeof (UINT64)];\r
+  BOOLEAN  Converted;\r
+\r
+  Converted = DxePrintLibPrint2ProtocolVaListToBaseList (\r
+                FALSE,\r
+                (CHAR8 *)FormatString,\r
+                Marker,\r
+                (BASE_LIST)BaseListMarker,\r
+                sizeof (BaseListMarker) - 8\r
+                );\r
+  if (!Converted) {\r
+    return 0;\r
+  }\r
 \r
   return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
 }\r
@@ -943,6 +962,7 @@ AsciiValueToString (
 #define PRECISION             BIT11\r
 #define ARGUMENT_REVERSED     BIT12\r
 #define COUNT_ONLY_NO_PRINT   BIT13\r
+#define UNSIGNED_TYPE         BIT14\r
 \r
 //\r
 // Record date and time information\r
@@ -1079,7 +1099,7 @@ InternalPrintLibSPrint (
 #define WARNING_STATUS_NUMBER         5\r
 #define ERROR_STATUS_NUMBER           33\r
 \r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mStatusString[] = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * CONST mStatusString[] = {\r
   "Success",                      //  RETURN_SUCCESS                = 0\r
   "Warning Unknown Glyph",        //  RETURN_WARN_UNKNOWN_GLYPH     = 1\r
   "Warning Delete Failure",       //  RETURN_WARN_DELETE_FAILURE    = 2\r
@@ -1429,10 +1449,18 @@ InternalPrintLibSPrintMarker (
         //\r
         // break skipped on purpose\r
         //\r
+      case 'u':\r
+        if ((Flags & RADIX_HEX) == 0) {\r
+          Flags &= ~((UINTN) (PREFIX_SIGN));\r
+          Flags |= UNSIGNED_TYPE;\r
+        }\r
+        //\r
+        // break skipped on purpose\r
+        //\r
       case 'd':\r
         if ((Flags & LONG_TYPE) == 0) {\r
           //\r
-          // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
+          // 'd', 'u', '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
@@ -1466,17 +1494,27 @@ InternalPrintLibSPrintMarker (
             Flags &= ~((UINTN) PREFIX_ZERO);\r
             Precision = 1;\r
           }\r
-          if (Value < 0) {\r
+          if (Value < 0 && (Flags & UNSIGNED_TYPE) == 0) {\r
             Flags |= PREFIX_SIGN;\r
             Prefix = '-';\r
             Value = -Value;\r
+          } else if ((Flags & UNSIGNED_TYPE) != 0 && (Flags & LONG_TYPE) == 0) {\r
+            //\r
+            // 'd', 'u', '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
         } else {\r
           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
+            // 'd', 'u', '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