This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] enable SI unit suffix in printf_size


Hi,

Recent discussions reminded me of something I wanted before; SI units
with the printf_size functions.  With the suggested patch below, if
you specify # with your lower case letter it will print, for example,
'Gi' as opposed to 'g'

Thanks,

-i
ianw@gelato.unsw.edu.au
http://www.gelato.unsw.edu.au

2005-10-19  Ian Wienand  <ianw@gelato.unsw.edu.au>

	* stdio-common/printf_size.c: enable use of alt modifier to show
	SI units
	* manual/stdio.texi : describe above

Index: manual/stdio.texi
===================================================================
RCS file: /cvs/glibc/libc/manual/stdio.texi,v
retrieving revision 1.134
diff -u -r1.134 stdio.texi
--- manual/stdio.texi	25 Sep 2005 18:24:55 -0000	1.134
+++ manual/stdio.texi	19 Oct 2005 02:46:14 -0000
@@ -3112,7 +3112,10 @@
 powers of 1024 or powers of 1000.  Which one is used depends on the
 format character specified while registered this handler.  If the
 character is of lower case, 1024 is used.  For upper case characters,
-1000 is used.
+1000 is used.  If you use lower case you can also specify the
+alternative (@samp{#}) modifier to show SI binary units (note that the
+default behaviour of @samp{#} to always print the decimal will be
+overridden in this case).
 
 The postfix tag corresponds to bytes, kilobytes, megabytes, gigabytes,
 etc.  The full table is:
Index: stdio-common/printf_size.c
===================================================================
RCS file: /cvs/glibc/libc/stdio-common/printf_size.c,v
retrieving revision 1.15
diff -u -r1.15 printf_size.c
--- stdio-common/printf_size.c	4 Aug 2004 21:43:30 -0000	1.15
+++ stdio-common/printf_size.c	19 Oct 2005 02:46:15 -0000
@@ -1,5 +1,5 @@
 /* Print size value using units for orders of magnitude.
-   Copyright (C) 1997-2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1997-2002, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
    Based on a proposal by Larry McVoy <lm@sgi.com>.
@@ -85,19 +85,23 @@
 			const void *const *args);
 
 
+
 int
 printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
 {
   /* Units for the both formats.  */
 #define BINARY_UNITS	" kmgtpezy"
 #define DECIMAL_UNITS	" KMGTPEZY"
-  static const char units[2][sizeof (BINARY_UNITS)] =
+#define SI_UNITS	"  KiMiGiTiPiEiZiYi"
+  static const char units[3][sizeof (SI_UNITS)] =
   {
     BINARY_UNITS,	/* For binary format.  */
-    DECIMAL_UNITS	/* For decimal format.  */
+    DECIMAL_UNITS,	/* For decimal format.  */
+    SI_UNITS		/* For SI unit format.  */
   };
-  const char *tag = units[isupper (info->spec) != 0];
+  const char *tag;
   int divisor = isupper (info->spec) ? 1000 : 1024;
+  int tag_inc;
 
   /* The floating-point value to output.  */
   union
@@ -118,6 +122,17 @@
   int done = 0;
   int wide = info->wide;
 
+  /* allow SI units as an alt (#) for 1024 divisor  */
+  if (info->alt && !isupper(info->spec))
+    {
+      tag = units[2];
+      tag_inc = 2;
+    }
+  else
+    {
+      tag = units[isupper (info->spec) != 0];
+      tag_inc = 1;
+    }
 
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
@@ -140,10 +155,10 @@
 	  negative = fpnum.ldbl.d < 0;
 	}
       else
-	while (fpnum.ldbl.d >= divisor && tag[1] != '\0')
+	while (fpnum.ldbl.d >= divisor && tag[tag_inc] != '\0')
 	  {
 	    fpnum.ldbl.d /= divisor;
-	    ++tag;
+	    tag += tag_inc;
 	  }
     }
   else
@@ -166,10 +181,10 @@
 	  negative = fpnum.dbl.d < 0;
 	}
       else
-	while (fpnum.dbl.d >= divisor && tag[1] != '\0')
+	while (fpnum.dbl.d >= divisor && tag[tag_inc] != '\0')
 	  {
 	    fpnum.dbl.d /= divisor;
-	    ++tag;
+	    tag += tag_inc;
 	  }
     }
 
@@ -205,10 +220,12 @@
   fp_info.spec = 'f';
   fp_info.prec = info->prec < 0 ? 3 : info->prec;
   fp_info.wide = wide;
-
+  /* Override alt (#) specifier when using SI units */
+  if (info->alt && !isupper(info->spec))
+    fp_info.alt = 0;
   if (fp_info.left && fp_info.pad == L' ')
     {
-      /* We must do the padding ourself since the unit character must
+      /* We must do the padding ourself since the unit characters must
 	 be placed before the padding spaces.  */
       fp_info.width = 0;
 
@@ -216,6 +233,8 @@
       if (done > 0)
 	{
 	  outchar (*tag);
+	  if (tag_inc == 2)
+	    outchar(*(tag + 1));
 	  if (info->width > done)
 	    PADN (' ', info->width - done);
 	}
@@ -223,12 +242,16 @@
   else
     {
       /* We can let __printf_fp do all the printing and just add our
-	 unit character afterwards.  */
-      fp_info.width = info->width - 1;
+	 unit characters afterwards.  */
+      fp_info.width = info->width - tag_inc;
 
       done = __printf_fp (fp, &fp_info, &ptr);
       if (done > 0)
-	outchar (*tag);
+	{
+	  outchar(*tag);
+	  if (tag_inc == 2)
+	    outchar(*(tag + 1));
+	}
     }
 
   return done;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]