On Wed, Jul 6, 2022 at 7:22 PM Kinney, Michael D <michael.d.kin...@intel.com> wrote:
> Hi Pedro, > > This is an interesting feature. > > It is backwards compatible since you are adding a format specifier to the > PrintLib class. > > There is a 2nd lib instance that needs to be updated, and that is > DxePrintLibPrint2Protocol in MdeModulePkg. > > I think using ANSI C %z specifier syntax assumes that sizeof(size_t) == > sizeof(UINTN) for all supported compilers/CPU archs. > The ANSI C 99 specification does not state that this is always true. If > may be true in practice for the compiler/CPU archs > currently supported by Tianocore. > > It would be good to add a STATIC_ASSERT() to check that this is true and > break the build if a compiler+CPU combination > is used where that assumption is false. Not sure if this should go in > Base.h with other STATIC_ASSERT()s for > types. Or if it should go in PrintLib.h where this assumption is being > made. > Hi Mike, How can sizeof(size_t) != sizeof(UINTN)? It seems to be quite a stretch to interpret the standard in a way that the native word size will not be able to store "the maximum size of a theoretically possible object of any type". In any case, getting the size_t type is non-trivial and as far as I can tell would either depend on a C library or C extension trickery to try to get the type of sizeof(Type). > I would like to see some more background on the motivation for adding this > feature. > I think the current workaround would be to typecast and integer of type > size_t to UINT64 and use %Ld or > typecase to UINT32 and use %d. > Ok, some background: I essentially starting looking at DebugLib and PrintLib and I found myself very surprised by a good chunk of decisions. The API is very similar to standard printf() but it lacks support for a good portion of specifiers; some specifiers it implements don't have the C99 standard meaning, like the ones it implements for integers (%x and %lx for hex, for instance) which were non-obviously overridden to mean print UINT32 and print UINT64. Because of that, I feel that maybe reworking this library (creating PrintLib2 or something, since we can't break the existing uses) would be a good idea to have a "principle of least surprise" compliant API and would help smoothen the confusion curve between userspace code and EDK2 firmware. Since reworking the whole of PrintLib is a non-trivial amount of work, I settled for this very tiny feature that doesn't break anyone's code and is very handy to avoid odd workarounds like casting everything to a UINT64 so you can print it with %lx. Obviously, if there's interest in getting a more standard environment[1] in EDK2 (and I personally, although possibly naiively, don't see the downside), going down a PrintLib2 in the long haul is a good idea. But this patch took me around 10 minutes to write up and is probably useful in its current form. Thanks, Pedro [1] Why do I want to get a more standardized environment? Well, I simply believe it smoothens the learning curve between userspace -> kernel -> bootloader -> firmware. A good chunk of kernels and bootloaders already have relatively standard C APIs, but firmware, at least in our case, is still lacking. Also, makes you less prone to mistakes. > > Thanks, > > Mike > > > > -----Original Message----- > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Pedro > Falcato > > Sent: Monday, July 4, 2022 6:16 PM > > To: devel@edk2.groups.io > > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Gao, Liming < > gaolim...@byosoft.com.cn>; Liu, Zhiguang > > <zhiguang....@intel.com> > > Subject: [edk2-devel] [PATCH v2] MdePkg/BasePrintLib: Add %z specifier > > > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3977 > > > > %z is used in standard C99 as the printf specifier for size_t types. > > Add support for it so we can portably print UINTN. > > > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > > Cc: Liming Gao <gaolim...@byosoft.com.cn> > > Cc: Zhiguang Liu <zhiguang....@intel.com> > > Signed-off-by: Pedro Falcato <pedro.falc...@gmail.com> > > --- > > MdePkg/Include/Library/PrintLib.h | 13 ++++++++----- > > MdePkg/Library/BasePrintLib/PrintLibInternal.c | 9 +++++++++ > > MdePkg/Library/BasePrintLib/PrintLibInternal.h | 1 + > > 3 files changed, 18 insertions(+), 5 deletions(-) > > > > diff --git a/MdePkg/Include/Library/PrintLib.h > b/MdePkg/Include/Library/PrintLib.h > > index 8d523cac52..0d67f62d3f 100644 > > --- a/MdePkg/Include/Library/PrintLib.h > > +++ b/MdePkg/Include/Library/PrintLib.h > > @@ -42,6 +42,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > - L, l > > - The number being printed is size UINT64. Only valid for types > X, x, and d. > > If this flag is not specified, then the number being printed is > size int. > > + - z > > + - The number being printed is of size UINTN. Only valid for types > X, x and d. > > + If this flag is not specified, then the number being printed is > size int. > > - NOTE: All invalid flags are ignored. > > > > [width]: > > @@ -73,18 +76,18 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > using this type too by making sure bits 8..15 of the argument > are set to 0. > > - x > > - The argument is an unsigned hexadecimal number. The characters > used are 0..9 and > > - A..F. If the flag 'L' is not specified, then the argument is > assumed > > + A..F. If the flags 'L', 'z' are not specified, then the > argument is assumed > > to be size int. This does not follow ANSI C. > > - X > > - The argument is an unsigned hexadecimal number and the number > is padded with > > - zeros. This is equivalent to a format string of "0x". If the > flag > > - 'L' is not specified, then the argument is assumed to be size > int. > > + zeros. This is equivalent to a format string of "0x". If the > flags > > + 'L', 'z' are not specified, then the argument is assumed to be > size int. > > This does not follow ANSI C. > > - d > > - - The argument is a signed decimal number. If the flag 'L' is > not specified, > > + - The argument is a signed decimal number. If the flags 'L', 'z' > are not specified, > > then the argument is assumed to be size int. > > - u > > - - The argument is a unsigned decimal number. If the flag 'L' is > not specified, > > + - The argument is a unsigned decimal number. If the flags 'L'. > 'z' are not specified, > > then the argument is assumed to be size int. > > - p > > - The argument is a pointer that is a (VOID *), and it is printed > as an > > diff --git a/MdePkg/Library/BasePrintLib/PrintLibInternal.c > b/MdePkg/Library/BasePrintLib/PrintLibInternal.c > > index 42b598a432..1cd99b2213 100644 > > --- a/MdePkg/Library/BasePrintLib/PrintLibInternal.c > > +++ b/MdePkg/Library/BasePrintLib/PrintLibInternal.c > > @@ -720,6 +720,9 @@ BasePrintLibSPrintMarker ( > > case 'l': > > Flags |= LONG_TYPE; > > break; > > + case 'z': > > + Flags |= SIZET_TYPE; > > + break; > > case '*': > > if ((Flags & PRECISION) == 0) { > > Flags |= PAD_TO_WIDTH; > > @@ -833,6 +836,12 @@ BasePrintLibSPrintMarker ( > > } else { > > Value = BASE_ARG (BaseListMarker, int); > > } > > + } else if ((Flags & SIZET_TYPE) != 0) { > > + if (BaseListMarker == NULL) { > > + Value = VA_ARG (VaListMarker, UINTN); > > + } else { > > + Value = BASE_ARG (BaseListMarker, UINTN); > > + } > > } else { > > if (BaseListMarker == NULL) { > > Value = VA_ARG (VaListMarker, INT64); > > diff --git a/MdePkg/Library/BasePrintLib/PrintLibInternal.h > b/MdePkg/Library/BasePrintLib/PrintLibInternal.h > > index 34d591c6fc..9193e6192b 100644 > > --- a/MdePkg/Library/BasePrintLib/PrintLibInternal.h > > +++ b/MdePkg/Library/BasePrintLib/PrintLibInternal.h > > @@ -29,6 +29,7 @@ > > #define ARGUMENT_REVERSED BIT12 > > #define COUNT_ONLY_NO_PRINT BIT13 > > #define UNSIGNED_TYPE BIT14 > > +#define SIZET_TYPE BIT15 > > > > // > > // Record date and time information > > -- > > 2.37.0 > > > > > > > > > > > > -- Pedro Falcato -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#91123): https://edk2.groups.io/g/devel/message/91123 Mute This Topic: https://groups.io/mt/92177290/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-