FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Device-mapper Development

 
 
LinkBack Thread Tools
 
Old 05-23-2012, 05:42 AM
Joe Perches
 
Default Add human-readable units modifier to vsnprintf()

On Wed, 2012-05-23 at 01:22 -0400, Kent Overstreet wrote:
> On Tue, May 22, 2012 at 10:10:48PM -0700, Joe Perches wrote:
> > On Wed, 2012-05-23 at 00:50 -0400, Kent Overstreet wrote:
> > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > []
> > > @@ -1002,6 +1023,7 @@ int format_decode(const char *fmt, struct printf_spec *spec)
> > > case ' ': spec->flags |= SPACE; break;
> > > case '#': spec->flags |= SPECIAL; break;
> > > case '0': spec->flags |= ZEROPAD; break;
> > > + case 'h': spec->flags |= HUNITS; break;
> > > default: found = false;
> > > }
> > >
> >
> > I think that doesn't work well because
> > gcc __attribute__((format(printf, x, y)))
> > verification fails.
>
> Yeah, I already ran into that. I was looking through the gcc docs to see
> if there was a way to add modifiers (how is it done for the other kernel
> specific format strings?) but I haven't found anything yet

It's done via %p extensions.
gcc doesn't care as long as the %p argument is a pointer.

> > It's also possible
> > to confuse it with printf's own 'h' /
> > integer precision use.
>
> Well, that's annoying. Any suggestions?

I gave you one already.

Use a new lib/vsprintf.c %p pointer extension like
"%pD" or "%pH" and use a pointer to the type as the
argument.

It's how it's done for an ipv4 address.
For instance:
be32 address = cpu_to_be32(0xc0a80101);
printk("%pI4" &address);
emits "192.168.1.1"



--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-23-2012, 06:04 AM
Kent Overstreet
 
Default Add human-readable units modifier to vsnprintf()

On Tue, May 22, 2012 at 10:42:40PM -0700, Joe Perches wrote:
> > Yeah, I already ran into that. I was looking through the gcc docs to see
> > if there was a way to add modifiers (how is it done for the other kernel
> > specific format strings?) but I haven't found anything yet
>
> It's done via %p extensions.
> gcc doesn't care as long as the %p argument is a pointer.

Ahh

>
> > > It's also possible
> > > to confuse it with printf's own 'h' /
> > > integer precision use.
> >
> > Well, that's annoying. Any suggestions?
>
> I gave you one already.

Missed the reason for your suggestion

>
> Use a new lib/vsprintf.c %p pointer extension like
> "%pD" or "%pH" and use a pointer to the type as the
> argument.

Only trouble is we lose the existing method of specifying the type of
the integer. New flag character would make much more sense... if gcc
could be persuaded.

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-23-2012, 06:12 AM
Joe Perches
 
Default Add human-readable units modifier to vsnprintf()

On Wed, 2012-05-23 at 02:04 -0400, Kent Overstreet wrote:
> Only trouble is we lose the existing method of specifying the type of
> the integer.

Hi again Kent.

My first suggestion to you was:
---------------------
> or maybe yet another lib/vsprintf pointer extension
> like %pD with some descriptors after the %pD for
> type, width and precision.
---------------------

For instance, internet addresses use pointer extensions
%pI4 and %pI6 for ipv4 and ipv6 addresses.

> New flag character would make much more sense... if gcc
> could be persuaded.

It can't be so persuaded though. Maybe a future gcc.

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 07-23-2012, 11:50 PM
Kent Overstreet
 
Default Add human-readable units modifier to vsnprintf()

Signed-off-by: Kent Overstreet <koverstreet@google.com>
---
lib/vsprintf.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index c3f36d41..16149dd 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -338,6 +338,7 @@ int num_to_str(char *buf, int size, unsigned long long num)
#define LEFT 16 /* left justified */
#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
+#define HUNITS 128 /* Human readable units, i.e. k/M/G/T */

enum format_type {
FORMAT_TYPE_NONE, /* Just a string part */
@@ -377,6 +378,7 @@ char *number(char *buf, char *end, unsigned long long num,
{
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
+ static const char units[] = "?kMGTPEZY";

char tmp[66];
char sign;
@@ -431,7 +433,26 @@ char *number(char *buf, char *end, unsigned long long num,
num >>= shift;
} while (num);
} else { /* base 10 */
- i = put_dec(tmp, num) - tmp;
+ if (spec.flags & HUNITS) {
+ int u, rem = 0;
+
+ for (u = 0; num >= 1024; u++) {
+ rem = num & ~(~0 << 10);
+ num >>= 10;
+ }
+
+ if (u) {
+ tmp[i++] = units[u];
+
+ if (num < 100) {
+ rem /= 100;
+ i = put_dec(tmp + i, rem) - tmp;
+ tmp[i++] = '.';
+ }
+ }
+ }
+
+ i = put_dec(tmp + i, num) - tmp;
}

/* printing 100 using %2d gives "100", not "00" */
@@ -1127,6 +1148,7 @@ int format_decode(const char *fmt, struct printf_spec *spec)
case ' ': spec->flags |= SPACE; break;
case '#': spec->flags |= SPECIAL; break;
case '0': spec->flags |= ZEROPAD; break;
+ case 'h': spec->flags |= HUNITS; break;
default: found = false;
}

--
1.7.7.3

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 

Thread Tools




All times are GMT. The time now is 01:01 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org