From owner-freebsd-bugs Thu Nov 21 23:10:03 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA29607 for bugs-outgoing; Thu, 21 Nov 1996 23:10:03 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id XAA29600; Thu, 21 Nov 1996 23:10:02 -0800 (PST) Resent-Date: Thu, 21 Nov 1996 23:10:02 -0800 (PST) Resent-Message-Id: <199611220710.XAA29600@freefall.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, dawes@physics.usyd.edu.au Received: from landfill.physics.usyd.edu.au (landfill.physics.usyd.edu.au [129.78.129.18]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id XAA29248 for ; Thu, 21 Nov 1996 23:05:50 -0800 (PST) Received: (from dawes@localhost) by landfill.physics.usyd.edu.au (8.8.2/8.8.2) id SAA04025; Fri, 22 Nov 1996 18:05:43 +1100 (EST) Message-Id: <199611220705.SAA04025@landfill.physics.usyd.edu.au> Date: Fri, 22 Nov 1996 18:05:43 +1100 (EST) From: dawes@physics.usyd.edu.au Reply-To: dawes@physics.usyd.edu.au To: FreeBSD-gnats-submit@freebsd.org Cc: dawes@physics.usyd.edu.au X-Send-Pr-Version: 3.2 Subject: bin/2080: The scanf family doesn't support the 'q' modifier Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >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: