delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/11/30/11:15:28

Date: Sat, 30 Nov 2002 16:19:15 +0000
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: printf and the 'hh' conversion specifier (C99) [PATCH]
Message-Id: <E18IAGz-0000S3-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Below is a patch to add support for the 'hh' conversion specifier.
This is shorter than a short - a char. The only change that concerns
me is:

    ARG(int);

switched to:

    ARG(signed);

I'm pretty sure this is equivalent. It seems to work OK - I ran
the Cygnus test suite (*) - tests/cygnus - and the results were
unaffected by this change.

(*) Eli suggested the Cygnus test suite as being hard on *scanf()
    and *printf() previously.

The patch also corrects the description of the 'L' conversion specifier -
this is only supposed to be used with doubles. long longs should use 'll'.
I haven't changed the code, so that we remain back compatible.

I'd like to use 'hh' in a patch to add support for C99's <inttypes.h>
sometime.

OK to commit?

Bye, Rich =]

Index: src/libc/ansi/stdio/doprnt.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/doprnt.c,v
retrieving revision 1.11
diff -p -c -3 -r1.11 doprnt.c
*** src/libc/ansi/stdio/doprnt.c	17 Oct 2002 23:00:24 -0000	1.11
--- src/libc/ansi/stdio/doprnt.c	30 Nov 2002 16:10:19 -0000
*************** static char decimal = '.';
*** 37,42 ****
--- 37,43 ----
  		flags&LONGDBL ? va_arg(argp, long long basetype) : \
  		flags&LONGINT ? va_arg(argp, long basetype) : \
  		flags&SHORTINT ? (short basetype)va_arg(argp, int) : \
+ 		flags&CHARINT ? (char basetype)va_arg(argp, int) : \
  		(basetype)va_arg(argp, int)
  
  static int nan_p = 0;
*************** static __inline__ char tochar(int n)
*** 59,68 ****
  #define	LONGINT		0x01		/* long integer */
  #define	LONGDBL		0x02		/* long double */
  #define	SHORTINT	0x04		/* short integer */
! #define	ALT		0x08		/* alternate form */
! #define	LADJUST		0x10		/* left adjustment */
! #define	ZEROPAD		0x20		/* zero (as opposed to blank) pad */
! #define	HEXPREFIX	0x40		/* add 0x or 0X prefix */
  
  static int cvtl(long double number, int prec, int flags, char *signp,
  	        unsigned char fmtch, char *startp, char *endp);
--- 60,70 ----
  #define	LONGINT		0x01		/* long integer */
  #define	LONGDBL		0x02		/* long double */
  #define	SHORTINT	0x04		/* short integer */
! #define	CHARINT		0x08		/* char */
! #define	ALT		0x10		/* alternate form */
! #define	LADJUST		0x20		/* left adjustment */
! #define	ZEROPAD		0x40		/* zero (as opposed to blank) pad */
! #define	HEXPREFIX	0x80		/* add 0x or 0X prefix */
  
  static int cvtl(long double number, int prec, int flags, char *signp,
  	        unsigned char fmtch, char *startp, char *endp);
*************** _doprnt(const char *fmt0, va_list argp, 
*** 192,198 ****
        flags |= LONGDBL;
        goto rflag;
      case 'h':
!       flags |= SHORTINT;
        goto rflag;
      case 'l':
        if (flags&LONGINT)
--- 194,205 ----
        flags |= LONGDBL;
        goto rflag;
      case 'h':
!       if (flags&SHORTINT) {
! 	flags |= CHARINT;
! 	flags &= ~SHORTINT;
!       } else {
! 	flags |= SHORTINT;
!       }
        goto rflag;
      case 'l':
        if (flags&LONGINT)
*************** _doprnt(const char *fmt0, va_list argp, 
*** 210,216 ****
        /*FALLTHROUGH*/
      case 'd':
      case 'i':
!       ARG(int);
        if ((long long)_ulonglong < 0)
        {
          _ulonglong = -_ulonglong;
--- 217,223 ----
        /*FALLTHROUGH*/
      case 'd':
      case 'i':
!       ARG(signed);
        if ((long long)_ulonglong < 0)
        {
          _ulonglong = -_ulonglong;
*************** _doprnt(const char *fmt0, va_list argp, 
*** 295,300 ****
--- 302,309 ----
  	*va_arg(argp, long *) = cnt;
        else if (flags & SHORTINT)
  	*va_arg(argp, short *) = cnt;
+       else if (flags & CHARINT)
+ 	*va_arg(argp, char *) = (char)cnt;
        else
  	*va_arg(argp, int *) = cnt;
        break;
Index: src/libc/ansi/stdio/printf.txh
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/printf.txh,v
retrieving revision 1.5
diff -p -c -3 -r1.5 printf.txh
*** src/libc/ansi/stdio/printf.txh	17 Oct 2002 10:17:18 -0000	1.5
--- src/libc/ansi/stdio/printf.txh	30 Nov 2002 16:10:19 -0000
*************** characters for a string. 
*** 65,73 ****
  
  @item
  
! An optional conversion qualifier, which may be @code{h} to specify
! @code{short}, @code{l} to specify long ints, or @code{L} to specify
! long doubles. Long long type can be specified by @code{L} or @code{ll}.
  
  @item
  
--- 65,74 ----
  
  @item
  
! An optional conversion qualifier, which may be @code{hh} to specify
! @code{char}, @code{h} to specify @code{short} integers, @code{l}
! to specify @code{long} integers, @code{ll} to specify
! @code{long long} integers, or @code{L} to specify @code{long} doubles.
  
  @item
  
Index: src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.123
diff -p -c -3 -r1.123 wc204.txi
*** src/docs/kb/wc204.txi	30 Nov 2002 09:49:47 -0000	1.123
--- src/docs/kb/wc204.txi	30 Nov 2002 16:10:26 -0000
*************** The function @code{_Exit} was added.
*** 788,790 ****
--- 788,795 ----
  
  @findex atoll
  The function @code{atoll} was added.
+ 
+ @findex _doprnt AT r{, and }hh AT r{ conversion qualifier}
+ @findex printf AT r{, and }hh AT r{ conversion qualifier}
+ The @code{hh} conversion qualifier is now supported by @code{_doprnt}
+ and the @code{printf} family of functions.
Index: tests/libc/ansi/stdio/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/stdio/makefile,v
retrieving revision 1.6
diff -p -c -3 -r1.6 makefile
*** tests/libc/ansi/stdio/makefile	22 May 2001 20:52:27 -0000	1.6
--- tests/libc/ansi/stdio/makefile	30 Nov 2002 16:10:26 -0000
*************** SRC += fseek2.c
*** 14,19 ****
--- 14,20 ----
  SRC += hello.c
  SRC += mktemp.c
  SRC += printf.c
+ SRC += printf2.c
  SRC += sscanf.c
  SRC += tmpnam.c
  SRC += tscanf.c
*** /dev/null	Sat Nov 30 16:14:34 2002
--- tests/libc/ansi/stdio/printf2.c	Sat Nov 30 16:06:40 2002
***************
*** 0 ****
--- 1,22 ----
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+ int
+ main (void)
+ {
+   signed char   sc = SCHAR_MAX;
+   unsigned char uc = UCHAR_MAX;
+ 
+   /* Normal operation */
+   printf("%hhd %hhi %hhu 0x%hhx 0x%hhX\n",
+ 	 sc, sc, uc, uc, uc);
+ 
+   /* Try truncating some ints */
+   printf("%hhd %hhi\n", 128, 128);
+ 
+   printf("%hhd %hhi %hhu 0x%hhx 0x%hhX\n",
+ 	 INT_MAX, INT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);
+ 
+   return(EXIT_SUCCESS);
+ }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019