This is the mail archive of the newlib@sourceware.org mailing list for the newlib 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]

fix missing *printf size modifiers


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

POSIX mandates %j ([u]intmax_t), %t (ptrdiff_t and unsigned counterpart),
%z ([s]size_t), and %hh ({signed,unsigned,} char printed as an integer)
modifiers.  I got tired of not having them in cygwin.  This patch assumes
that intmax_t, ptrdiff_t, and size_t will be equivalent in size to one of
short, int, long, or long long for all newlib targets, even though POSIX
allows for them to be distinct widths on weirdnix systems.

2006-09-02  Eric Blake  <ebb9@byu.net>

	* libc/stdio/vfprintf.c (_vfprintf_r, get_arg): Add 'hh', 'j',
	't', and 'z' modifiers.

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFE+Ygs84KuGfSFAYARAmcIAJ4sLNebqpKEsqi7TaSYnwS1E+ptxwCgg0J3
/GOXq1mhvq3NiDm0C06oRSc=
=czVY
-----END PGP SIGNATURE-----
Index: libc/stdio/vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.44
diff -u -p -r1.44 vfprintf.c
--- libc/stdio/vfprintf.c	14 Jun 2006 20:49:11 -0000	1.44
+++ libc/stdio/vfprintf.c	2 Sep 2006 13:31:40 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1990, 2006 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
@@ -372,6 +372,7 @@ _EXFUN(get_arg, (struct _reent *data, in
 #define	SHORTINT	0x040		/* short integer */
 #define	ZEROPAD		0x080		/* zero (as opposed to blank) pad */
 #define FPT		0x100		/* Floating point number */
+#define CHARINT		0x200		/* char as integer */
 
 int _EXFUN(_VFPRINTF_R, (struct _reent *, FILE *, _CONST char *, va_list));
 
@@ -517,20 +518,24 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap)
 	(flags&QUADINT ? GET_ARG (N, ap, quad_t) : \
 	    flags&LONGINT ? GET_ARG (N, ap, long) : \
 	    flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
+	    flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
 	    (long)GET_ARG (N, ap, int))
 #define	UARG() \
 	(flags&QUADINT ? GET_ARG (N, ap, u_quad_t) : \
 	    flags&LONGINT ? GET_ARG (N, ap, u_long) : \
 	    flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
+	    flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
 	    (u_long)GET_ARG (N, ap, u_int))
 #else
 #define	SARG() \
 	(flags&LONGINT ? GET_ARG (N, ap, long) : \
 	    flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
+	    flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
 	    (long)GET_ARG (N, ap, int))
 #define	UARG() \
 	(flags&LONGINT ? GET_ARG (N, ap, u_long) : \
 	    flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
+	    flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
 	    (u_long)GET_ARG (N, ap, u_int))
 #endif
 
@@ -747,7 +752,12 @@ reswitch:	switch (ch) {
 			goto rflag;
 #endif
 		case 'h':
-			flags |= SHORTINT;
+			if (*fmt == 'h') {
+				fmt++;
+				flags |= CHARINT;
+			} else {
+				flags |= SHORTINT;
+			}
 			goto rflag;
 		case 'l':
 			if (*fmt == 'l') {
@@ -760,6 +770,43 @@ reswitch:	switch (ch) {
 		case 'q':
 			flags |= QUADINT;
 			goto rflag;
+		case 'j':
+		  if (sizeof (intmax_t) == sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    flags |= QUADINT;
+		  goto rflag;
+		case 'z':
+		  if (sizeof (size_t) < sizeof (int))
+		    /* POSIX states size_t is 16 or more bits, as is short.  */
+		    flags |= SHORTINT;
+		  else if (sizeof (size_t) == sizeof (int))
+		    /* no flag needed */;
+		  else if (sizeof (size_t) <= sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    /* POSIX states that at least one programming
+		       environment must support size_t no wider than
+		       long, but that means other environments can
+		       have size_t as wide as long long.  */
+		    flags |= QUADINT;
+		  goto rflag;
+		case 't':
+		  if (sizeof (ptrdiff_t) < sizeof (int))
+		    /* POSIX states ptrdiff_t is 16 or more bits, as
+		       is short.  */
+		    flags |= SHORTINT;
+		  else if (sizeof (ptrdiff_t) == sizeof (int))
+		    /* no flag needed */;
+		  else if (sizeof (ptrdiff_t) <= sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    /* POSIX states that at least one programming
+		       environment must support ptrdiff_t no wider than
+		       long, but that means other environments can
+		       have ptrdiff_t as wide as long long.  */
+		    flags |= QUADINT;
+		  goto rflag;
 		case 'c':
 		case 'C':
 			cp = buf;
@@ -916,6 +963,8 @@ reswitch:	switch (ch) {
 				*GET_ARG (N, ap, long_ptr_t) = ret;
 			else if (flags & SHORTINT)
 				*GET_ARG (N, ap, short_ptr_t) = ret;
+			else if (flags & CHARINT)
+				*GET_ARG (N, ap, char_ptr_t) = ret;
 			else
 				*GET_ARG (N, ap, int_ptr_t) = ret;
 			continue;	/* no output */
@@ -1526,7 +1575,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
   ACTION action;
   int pos, last_arg;
   int max_pos_arg = n;
-  enum types { INT, LONG_INT, SHORT_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
+  enum types { INT, LONG_INT, SHORT_INT, CHAR_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
 #ifdef _MB_CAPABLE
   wchar_t wc;
   mbstate_t wc_state;
@@ -1585,7 +1634,13 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
 	      switch (ch)
 		{
 		case 'h':
-		  flags |= SHORTINT;
+		  if (*fmt == 'h')
+		    {
+		      flags |= CHARINT;
+		      ++fmt;
+		    }
+		  else
+		    flags |= SHORTINT;
 		  break;
 		case 'L':
 		  flags |= LONGDBL;
@@ -1593,6 +1648,43 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
 		case 'q':
 		  flags |= QUADINT;
 		  break;
+		case 'j':
+		  if (sizeof (intmax_t) == sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    flags |= QUADINT;
+		  break;
+		case 'z':
+		  if (sizeof (size_t) < sizeof (int))
+		    /* POSIX states size_t is 16 or more bits, as is short.  */
+		    flags |= SHORTINT;
+		  else if (sizeof (size_t) == sizeof (int))
+		    /* no flag needed */;
+		  else if (sizeof (size_t) <= sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    /* POSIX states that at least one programming
+		       environment must support size_t no wider than
+		       long, but that means other environments can
+		       have size_t as wide as long long.  */
+		    flags |= QUADINT;
+		  break;
+		case 't':
+		  if (sizeof (ptrdiff_t) < sizeof (int))
+		    /* POSIX states ptrdiff_t is 16 or more bits, as
+		       is short.  */
+		    flags |= SHORTINT;
+		  else if (sizeof (ptrdiff_t) == sizeof (int))
+		    /* no flag needed */;
+		  else if (sizeof (ptrdiff_t) <= sizeof (long))
+		    flags |= LONGINT;
+		  else
+		    /* POSIX states that at least one programming
+		       environment must support ptrdiff_t no wider than
+		       long, but that means other environments can
+		       have ptrdiff_t as wide as long long.  */
+		    flags |= QUADINT;
+		  break;
 		case 'l':
 		default:
 		  if (*fmt == 'l')
@@ -1621,6 +1713,8 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
 		      spec_type = LONG_INT;
 		    else if (flags & SHORTINT)
 		      spec_type = SHORT_INT;
+		    else if (flags & CHARINT)
+		      spec_type = CHAR_INT;
 #ifndef _NO_LONGLONG
 		    else if (flags & QUADINT)
 		      spec_type = QUAD_INT;
@@ -1676,6 +1770,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
 			args[numargs++].val_wint_t = va_arg (*ap, wint_t);
 			break;
 		      case CHAR:
+		      case CHAR_INT:
 		      case SHORT_INT:
 		      case INT:
 			args[numargs++].val_int = va_arg (*ap, int);
@@ -1761,6 +1856,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numar
 	  args[numargs++].val_wint_t = va_arg (*ap, wint_t);
 	  break;
 	case INT:
+	case CHAR_INT:
 	case SHORT_INT:
 	case CHAR:
 	default:

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