Date: Sat, 30 Nov 2002 16:19:15 +0000 From: "Richard Dawe" 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: 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 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 + #include + #include + + 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); + }