[BUG] wprintf(L"%s", str) expects str to be wide

Craig Howland howland@LGSInnovations.com
Fri Jan 11 17:03:00 GMT 2013


On 01/11/2013 11:12 AM, Corinna Vinschen wrote:
> Here's a matching patch.  I tested it under Cygwin by disabling
> _MB_CAPABLE when building vfwprintf.c.  Please review.  If that's ok,
> I'll check it in.
>
>
> Thanks,
> Corinna
>
>
> 	* vfwprintf.c (_VFWPRINTF_R): Add code to correctly handle 's'
> 	format specifier on not _MB_CAPABLE targets.  Fix a formatting
> 	glitch in _MB_CAPABLE enabled code.  Add a missing 'L' specifier.
>
>
> Index: libc/stdio/vfwprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/vfwprintf.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 vfwprintf.c
> --- libc/stdio/vfwprintf.c	10 Aug 2012 09:37:32 -0000	1.10
> +++ libc/stdio/vfwprintf.c	11 Jan 2013 16:10:34 -0000
> @@ -1171,11 +1171,11 @@ string:
>   					insize = strlen(arg);
>   				if (insize>= BUF) {
>   				    if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
> -								== NULL) {
> -							fp->_flags |= __SERR;
> -							goto error;
> -						}
> -						cp = malloc_buf;
> +					== NULL) {
> +						fp->_flags |= __SERR;
> +						goto error;
> +					}
> +					cp = malloc_buf;
>   				} else
>   					cp = buf;
>   				memset ((_PTR)&ps, '\0', sizeof (mbstate_t));
> @@ -1195,9 +1195,31 @@ string:
>   				*p = L'\0';
>   				size = p - cp;
>   			}
> -			else
> +#else
> +			if (ch != L'S'&&  !(flags&  LONGINT)) {
> +				char *arg = (char *) cp;
> +				size_t insize = 0;
> +
> +				if (prec>= 0) {
> +					char *p = memchr (arg, '\0', prec);
> +					insize = p ? p - arg : prec;
> +				} else
> +					insize = strlen (arg);
> +				if (insize>= BUF) {
> +				    if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
> +					== NULL) {
> +						fp->_flags |= __SERR;
> +						goto error;
> +					}
> +					cp = malloc_buf;
> +				} else
> +					cp = buf;
> +				for (size = 0; size<  insize; ++size)
> +					cp[size] = arg[size];
> +				cp[size] = L'\0';
> +			}
>   #endif /* _MB_CAPABLE */
> -			if (prec>= 0) {
> +			else if (prec>= 0) {
>   				/*
>   				 * can't use wcslen; can only look for the
>   				 * NUL in the first `prec' characters, and
> @@ -1222,7 +1244,7 @@ string:
>   		case L'X':
>   			xdigs = L"0123456789ABCDEF";
>   			goto hex;
> -		case 'x':
> +		case L'x':
>   			xdigs = L"0123456789abcdef";
>   hex:			_uquad = UARG ();
>   			base = HEX;
>
>
Corinna:
      Looks good.  (Good catch on the case 'x', too.)  One very minor thing, to 
be very gung-ho, should you care to bother:

insize = p ? p - arg : prec;	// works

insize = (p!=NULL) ? p - arg : prec;	// cleaner

(There's tons of the former, of course, and realistically NULL will never be 
other than 0.)
      Of course, it will be interesting to see if this does fix Konstantin's 
problem, since we're only theorizing that he does not have MB.  Hopefully.
                 Craig



More information about the Newlib mailing list