Date: Fri, 22 Nov 1996 18:05:43 +1100 (EST) From: dawes@physics.usyd.edu.au To: FreeBSD-gnats-submit@freebsd.org Cc: dawes@physics.usyd.edu.au Subject: bin/2080: The scanf family doesn't support the 'q' modifier Message-ID: <199611220705.SAA04025@landfill.physics.usyd.edu.au> Resent-Message-ID: <199611220710.XAA29600@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 2080
>Category: bin
>Synopsis: The scanf family doesn't support 'q' modifier
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Nov 21 23:10:00 PST 1996
>Last-Modified:
>Originator: David Dawes
>Organization:
University of Sydney, Australia
>Release: FreeBSD 3.0-CURRENT i386
>Environment:
>Description:
fscanf(3) and related functions don't support the 'q' modifier, so can't read
into types quad_t or u_quad_t. The printf functions do support this.
>How-To-Repeat:
It is clear that this support is missing by checking libc/stdio/vfscanf.c
and the fscanf(3) man page.
>Fix:
The following patch works for me. There may be better ways to do this.
Index: scanf.3
===================================================================
RCS file: /home/cvs/src/lib/libc/stdio/scanf.3,v
retrieving revision 1.2
diff -c -r1.2 scanf.3
*** scanf.3 1996/03/27 20:48:47 1.2
--- scanf.3 1996/11/22 06:48:04
***************
*** 171,176 ****
--- 171,185 ----
(This type is not implemented; the
.Cm L
flag is currently ignored.)
+ .It Cm q
+ Indicates either that the conversion will be one of
+ .Cm dioux
+ or
+ .Cm n
+ and the next pointer is a pointer to a
+ .Em long long int
+ (rather than
+ .Em int ) ,
.El
.Pp
In addition to these flags,
Index: vfscanf.c
===================================================================
RCS file: /home/cvs/src/lib/libc/stdio/vfscanf.c,v
retrieving revision 1.3
diff -c -r1.3 vfscanf.c
*** vfscanf.c 1996/06/22 10:34:06 1.3
--- vfscanf.c 1996/11/22 07:03:20
***************
*** 66,71 ****
--- 66,72 ----
#define SUPPRESS 0x08 /* suppress assignment */
#define POINTER 0x10 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x20 /* do not skip blanks */
+ #define QUAD 0x400
/*
* The following are used in numeric conversions only:
***************
*** 87,93 ****
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
! #define CT_INT 3 /* integer, i.e., strtol or strtoul */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#define u_char unsigned char
--- 88,94 ----
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
! #define CT_INT 3 /* integer, i.e., strtoq or strtouq */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#define u_char unsigned char
***************
*** 113,120 ****
register char *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
! int base; /* base argument to strtol/strtoul */
! u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
--- 114,121 ----
register char *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
! int base; /* base argument to strtoq/strtouq */
! u_quad_t(*ccfn)(); /* conversion function (strtoq/strtouq) */
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
***************
*** 166,171 ****
--- 167,175 ----
case 'l':
flags |= LONG;
goto again;
+ case 'q':
+ flags |= QUAD;
+ goto again;
case 'L':
flags |= LONGDBL;
goto again;
***************
*** 190,202 ****
/* FALLTHROUGH */
case 'd':
c = CT_INT;
! ccfn = (u_long (*)())strtol;
base = 10;
break;
case 'i':
c = CT_INT;
! ccfn = (u_long (*)())strtol;
base = 0;
break;
--- 194,206 ----
/* FALLTHROUGH */
case 'd':
c = CT_INT;
! ccfn = (u_quad_t (*)())strtoq;
base = 10;
break;
case 'i':
c = CT_INT;
! ccfn = (u_quad_t (*)())strtoq;
base = 0;
break;
***************
*** 205,217 ****
/* FALLTHROUGH */
case 'o':
c = CT_INT;
! ccfn = strtoul;
base = 8;
break;
case 'u':
c = CT_INT;
! ccfn = strtoul;
base = 10;
break;
--- 209,221 ----
/* FALLTHROUGH */
case 'o':
c = CT_INT;
! ccfn = strtouq;
base = 8;
break;
case 'u':
c = CT_INT;
! ccfn = strtouq;
base = 10;
break;
***************
*** 221,227 ****
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
c = CT_INT;
! ccfn = strtoul;
base = 16;
break;
--- 225,231 ----
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
c = CT_INT;
! ccfn = strtouq;
base = 16;
break;
***************
*** 253,259 ****
case 'p': /* pointer format is like hex */
flags |= POINTER | PFXOK;
c = CT_INT;
! ccfn = strtoul;
base = 16;
break;
--- 257,263 ----
case 'p': /* pointer format is like hex */
flags |= POINTER | PFXOK;
c = CT_INT;
! ccfn = strtouq;
base = 16;
break;
***************
*** 264,269 ****
--- 268,275 ----
*va_arg(ap, short *) = nread;
else if (flags & LONG)
*va_arg(ap, long *) = nread;
+ else if (flags & QUAD)
+ *va_arg(ap, quad_t *) = nread;
else
*va_arg(ap, int *) = nread;
continue;
***************
*** 278,284 ****
if (isupper(c))
flags |= LONG;
c = CT_INT;
! ccfn = (u_long (*)())strtol;
base = 10;
break;
}
--- 284,290 ----
if (isupper(c))
flags |= LONG;
c = CT_INT;
! ccfn = (u_quad_t (*)())strtoq;
base = 10;
break;
}
***************
*** 420,426 ****
continue;
case CT_INT:
! /* scan an integer as if by strtol/strtoul */
#ifdef hardway
if (width == 0 || width > sizeof(buf) - 1)
width = sizeof(buf) - 1;
--- 426,432 ----
continue;
case CT_INT:
! /* scan an integer as if by strtoq/strtouq */
#ifdef hardway
if (width == 0 || width > sizeof(buf) - 1)
width = sizeof(buf) - 1;
***************
*** 538,553 ****
(void) ungetc(c, fp);
}
if ((flags & SUPPRESS) == 0) {
! u_long res;
*p = 0;
res = (*ccfn)(buf, (char **)NULL, base);
if (flags & POINTER)
! *va_arg(ap, void **) = (void *)res;
else if (flags & SHORT)
*va_arg(ap, short *) = res;
else if (flags & LONG)
*va_arg(ap, long *) = res;
else
*va_arg(ap, int *) = res;
nassigned++;
--- 544,562 ----
(void) ungetc(c, fp);
}
if ((flags & SUPPRESS) == 0) {
! u_quad_t res;
*p = 0;
res = (*ccfn)(buf, (char **)NULL, base);
if (flags & POINTER)
! *va_arg(ap, void **) =
! (void *)(u_long)res;
else if (flags & SHORT)
*va_arg(ap, short *) = res;
else if (flags & LONG)
*va_arg(ap, long *) = res;
+ else if (flags & QUAD)
+ *va_arg(ap, quad_t *) = res;
else
*va_arg(ap, int *) = res;
nassigned++;
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611220705.SAA04025>
