This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: scanf and "-0x", "-nan", "inf"
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Tue, 22 May 2007 17:00:37 +0000 (UTC)
- Subject: Re: scanf and "-0x", "-nan", "inf"
- References: <loom.20070522T165326-534@post.gmane.org>
Eric Blake <ebb9 <at> byu.net> writes:
> Bugs that I am still aware of:
On platforms with 32-bit long but 64-bit void* (yes, such horrid platforms
exist, at least in the form of 64-bit Windows - what were they thinking?):
void *p = 0x1ffffff00;
void *q;
char buf[20];
sprintf(buf, "%p", p);
sscanf(buf, "%p", &q);
assert(p == q);
Fixed like so:
2007-05-22 Eric Blake <ebb9@byu.net>
* libc/stdio/vfprintf.c (_VFPRINTF_R): Don't truncate %p when
sizeof(void*) is 8 but sizeof(long) is 4.
* libc/stdio/vfscanf.c (__SVFSCANF_R): Likewise.
Index: libc/stdio/vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.60
diff -u -p -r1.60 vfprintf.c
--- libc/stdio/vfprintf.c 18 May 2007 14:33:30 -0000 1.60
+++ libc/stdio/vfprintf.c 22 May 2007 16:49:34 -0000
@@ -1017,7 +1017,7 @@ reswitch: switch (ch) {
* -- ANSI X3J11
*/
/* NOSTRICT */
- _uquad = (u_long)(unsigned _POINTER_INT)GET_ARG (N, ap,
void_ptr_t);
+ _uquad = (uintptr_t) GET_ARG (N, ap, void_ptr_t);
base = HEX;
xdigs = "0123456789abcdef";
flags |= HEXPREFIX;
Index: libc/stdio/vfscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfscanf.c,v
retrieving revision 1.36
diff -u -p -r1.36 vfscanf.c
--- libc/stdio/vfscanf.c 18 May 2007 14:33:30 -0000 1.36
+++ libc/stdio/vfscanf.c 22 May 2007 16:49:34 -0000
@@ -993,7 +993,19 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap
*p = 0;
res = (*ccfn) (rptr, buf, (char **) NULL, base);
if (flags & POINTER)
- *(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
+ {
+ void **vp = GET_ARG (N, ap, void **);
+#ifndef _NO_LONGLONG
+ if (sizeof (uintptr_t) > sizeof (u_long))
+ {
+ u_long_long resll;
+ resll = _strtoull_r (rptr, buf, (char **) NULL, base);
+ *vp = (void *) (uintptr_t) resll;
+ }
+ else
+#endif _NO_LONGLONG
+ *vp = (void *) (uintptr_t) res;
+ }
#ifdef _WANT_IO_C99_FORMATS
else if (flags & CHAR)
{