Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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:




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611220705.SAA04025>