printf %1$lc

Jeff Johnston jjohnstn@redhat.com
Wed Apr 25 20:05:00 GMT 2007


Patch checked in.  Thanks.

-- Jeff J.

Eric Blake wrote:
> Another bug (maybe I'm having too much fun finding all these printf 
> anomalies? :).  If wint_t promotes differently than int, then %1$lc was broken 
> (but %1$C worked).  While I was at it, I tried to reduce code size a bit.
> 
> 2007-04-24  Eric Blake  <ebb9@byu.net>
> 
> 	* libc/stdio/vfprintf.c (get_arg): Support %1$lc.  Simplify types
> 	that promote to int.
> 
> Index: libc/stdio/vfprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
> retrieving revision 1.53
> diff -u -r1.53 vfprintf.c
> --- libc/stdio/vfprintf.c	24 Apr 2007 20:09:50 -0000	1.53
> +++ libc/stdio/vfprintf.c	24 Apr 2007 20:27:22 -0000
> @@ -1603,7 +1603,8 @@
>    ACTION action;
>    int pos, last_arg;
>    int max_pos_arg = n;
> -  enum types { INT, LONG_INT, SHORT_INT, CHAR_INT, QUAD_INT, CHAR, CHAR_PTR, 
> DOUBLE, LONG_DOUBLE, WIDE_CHAR };
> +  /* Only need types that can be reached via vararg promotions.  */
> +  enum types { INT, LONG_INT, QUAD_INT, CHAR_PTR, DOUBLE, LONG_DOUBLE, 
> WIDE_CHAR };
>  #ifdef _MB_CAPABLE
>    wchar_t wc;
>    mbstate_t wc_state;
> @@ -1662,13 +1663,7 @@
>  	      switch (ch)
>  		{
>  		case 'h':
> -		  if (*fmt == 'h')
> -		    {
> -		      flags |= CHARINT;
> -		      ++fmt;
> -		    }
> -		  else
> -		    flags |= SHORTINT;
> +                  /* No flag needed, since short and char promote to int.  */
>  		  break;
>  		case 'L':
>  		  flags |= LONGDBL;
> @@ -1683,10 +1678,7 @@
>  		    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))
> +		  if (sizeof (size_t) <= sizeof (int))
>  		    /* no flag needed */;
>  		  else if (sizeof (size_t) <= sizeof (long))
>  		    flags |= LONGINT;
> @@ -1698,11 +1690,7 @@
>  		    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))
> +		  if (sizeof (ptrdiff_t) <= sizeof (int))
>  		    /* no flag needed */;
>  		  else if (sizeof (ptrdiff_t) <= sizeof (long))
>  		    flags |= LONGINT;
> @@ -1739,10 +1727,6 @@
>  		  case 'u':
>  		    if (flags & LONGINT)
>  		      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;
> @@ -1775,7 +1759,10 @@
>  		    spec_type = CHAR_PTR;
>  		    break;
>  		  case 'c':
> -		    spec_type = CHAR;
> +		    if (flags & LONGINT)
> +		      spec_type = WIDE_CHAR;
> +		    else
> +		      spec_type = INT;
>  		    break;
>  		  case 'C':
>  		    spec_type = WIDE_CHAR;
> @@ -1799,9 +1786,6 @@
>  		      case WIDE_CHAR:
>  			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);
>  			break;
> @@ -1886,9 +1870,6 @@
>  	  args[numargs++].val_wint_t = va_arg (*ap, wint_t);
>  	  break;
>  	case INT:
> -	case CHAR_INT:
> -	case SHORT_INT:
> -	case CHAR:
>  	default:
>  	  args[numargs++].val_int = va_arg (*ap, int);
>  	  break;
> 
> 



More information about the Newlib mailing list