Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Oct 2002 17:17:20 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        "David O'Brien" <obrien@FreeBSD.ORG>
Cc:        John Baldwin <jhb@FreeBSD.ORG>, Mike Barcroft <mike@FreeBSD.ORG>, <freebsd-arch@FreeBSD.ORG>, Andrew Gallatin <gallatin@cs.duke.edu>
Subject:   Re: lp64 vs lp32 printf
Message-ID:  <20021010162920.Y8030-100000@gamplex.bde.org>
In-Reply-To: <20021009220522.GA65943@dragon.nuxi.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 9 Oct 2002, David O'Brien wrote:

> How is this patch?
>
> Index: contrib/gcc/c-format.c
> ===================================================================
> RCS file: /home/ncvs/src/contrib/gcc/c-format.c,v
> retrieving revision 1.5
> diff -u -r1.5 c-format.c
> --- contrib/gcc/c-format.c	12 Jul 2002 00:49:52 -0000	1.5
> +++ contrib/gcc/c-format.c	9 Oct 2002 21:52:40 -0000
> @@ -795,10 +795,12 @@
>       The format %D provides a hexdump given a pointer and separator string:
>       ("%6D", ptr, ":")		-> XX:XX:XX:XX:XX:XX
>       ("%*D", len, ptr, " ")	-> XX XX XX XX ...
> +     The format %H is a version of %x that allows for a sign
> +     (e.g. -0x10 instead of 0xfffffff0, or +0x10).

I'm not sure if I like 'H'.  It's closer to the floating point specifiers
[EFG] than to the hex specifiers [xX].

The following comment assuems that %H and %+ have been fixed.  Currently,
plain %H is equivalent to %x, and %+H gives the non-broken %H but not
the normal userland behaviour for %+.

This format doesn't "allow" for a sign.  It gives one if the value is
negative when cast to a signed integer of the relevant size.  It does
not give one if this value is positive, and it does not give an 0x
prefix,  so +0x10 is a bad example.  %+H would give +10 in the same way
that %+d would give +16 if %+ actually worked in the kernel; %#+H would
also give the 0x prefix.  0xfffffff0 being printed as -0x10 is a bad
example.  0xfffffffff0 is only printed as -10 (not -0x10) on 32-bit
2's complement machines.  -0x10 is printed as -0x10.

There should be a comma after "e.g.".

Correctly the comment gives:

      The format %H is like %x except it takes a signed (int or long
      long) arg instead of an unsigned (int, long, long long) or
      uintmax_t arg, and prints in "signed hex" format instead of hex
      format (e.g., -16 is printed as "-10", and 16 is printed as "10").

>    { "D",   1, STD_EXT, { T89_C,  BADLEN,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",      "cR" },
>    { "b",   1, STD_EXT, { T89_C,  BADLEN,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",      ""   },
> -  { "rz",  0, STD_EXT, { T89_I,  BADLEN,   BADLEN,   T89_L,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",  "i"  },
> +  { "rH",  0, STD_EXT, { T89_I,  BADLEN,   BADLEN,   T89_L,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",  "i"  },

Try adding long long (ugh) support here.  It is implemented for %H in
printf(9), since %H mostly uses the same code as %x.

> Index: share/man/man9/printf.9
> ===================================================================
> RCS file: /home/ncvs/src/share/man/man9/printf.9,v
> retrieving revision 1.3
> diff -u -r1.3 printf.9
> --- share/man/man9/printf.9	1 Oct 2001 16:09:25 -0000	1.3
> +++ share/man/man9/printf.9	9 Oct 2002 21:55:51 -0000
> ...
> @@ -102,6 +106,12 @@
>  The string is used as a delimiter between individual bytes.
>  If present, a width directive will specify the number of bytes to display.
>  By default, 16 bytes of data are output.
> +.Pp
> +The
> +.Cm \&%H
> +identifier is a version of
> +.Cm \&%x
> +that allows for a sign (e.g. -0x10 instead of 0xfffffff0, or +0x10).

The details mostly belong here, not in gcc.  More details: If the arg
is negative, then a "-" followed by the negation of the arg (in infinite
precision) is printed (in hex).  The current implementation doesn't
actually use infinite precision and only works on normal 2's complement
machines.  E.g., it prints -1 as "0" on normal 1's complement machines,
and it has overflow problems negating INT_MAX.

I only tested this behaviour by reading the code.

> Index: sys/kern/subr_prf.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/kern/subr_prf.c,v
> retrieving revision 1.88
> diff -u -r1.88 subr_prf.c
> --- sys/kern/subr_prf.c	28 Sep 2002 21:34:31 -0000	1.88
> +++ sys/kern/subr_prf.c	9 Oct 2002 21:49:08 -0000
> @@ -662,7 +662,7 @@
>  		case 'X':
>  			base = 16;
>  			goto handle_nosign;
> -		case 'z':
> +		case 'H':
>  			base = 16;
>  			if (sign)
>  				goto handle_sign;
>

OK.  jhb has a patch to make plain %H actually work.

Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021010162920.Y8030-100000>