[RFA] Add hh and ll modifiers to scanf functions

Corinna Vinschen vinschen@redhat.com
Mon Mar 31 10:00:00 GMT 2003


Hi,

the below patch adds size modifiers 'hh' and 'll' to the scanf routines.
These modifiers are defined by SUSv3, see e. g.
http://www.opengroup.org/onlinepubs/007904975/toc.htm

I also updated the description in stdio/sscanf.c.  However, I don't
quite see a reason to keep this description in sscanf.c. It's not
the "natural" point for that, IMHO.  Should that be moved to vfscanf.c?

Corinna

2003-03-31  Corinna Vinschen  <corinna@vinschen.de>

	* libc/stdio/sscanf.c: Update flags description.
	* libc/stdio/vfscanf.c: Add CHAR flag value to denote 8 bit target
	type.
	(__svfscanf_r): Add 'hh' and 'll' handling.

Index: libc/stdio/sscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/sscanf.c,v
retrieving revision 1.3
diff -p -u -r1.3 sscanf.c
--- libc/stdio/sscanf.c	20 Apr 2001 22:50:51 -0000	1.3
+++ libc/stdio/sscanf.c	31 Mar 2003 09:49:19 -0000
@@ -152,22 +152,31 @@ DESCRIPTION
 
 
 .Modifier   Type(s)
-.   h       d, i, o, u, x     convert input to short,
+.   hh      d, i, o, u, x, n  convert input to char,
+.                             store in char object
+.
+.   h       d, i, o, u, x, n  convert input to short,
 .                             store in short object
 .
 .   h       D, I, O, U, X     no effect
-.           e, f, c, s, n, p
+.           e, f, c, s, p
 .
-.   l       d, i, o, u, x     convert input to long,
+.   l       d, i, o, u, x, n  convert input to long,
 .                             store in long object
 .
 .   l       e, f, g           convert input to double
 .                             store in a double object
 .
 .   l       D, I, O, U, X     no effect
-.           c, s, n, p
+.           c, s, p
+.
+.   ll      d, i, o, u, x, n  convert to long long,
+.                             store in long long
+.
+.   L       d, i, o, u, x, n  convert to long long,
+.                             store in long long
 .
-.   L       d, i, o, u, x     convert to long double,
+.   L       e, f, g, E, G     convert to long double,
 .                             store in long double
 .
 .   L      all others         no effect
Index: libc/stdio/vfscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfscanf.c,v
retrieving revision 1.13
diff -p -u -r1.13 vfscanf.c
--- libc/stdio/vfscanf.c	20 Mar 2003 17:23:57 -0000	1.13
+++ libc/stdio/vfscanf.c	31 Mar 2003 09:49:20 -0000
@@ -151,11 +151,12 @@ extern _LONG_DOUBLE _strtold _PARAMS((ch
  */
 
 #define	LONG		0x01	/* l: long or double */
-#define	LONGDBL		0x02	/* L: long double or long long */
+#define	LONGDBL		0x02	/* L/ll: long double or long long */
 #define	SHORT		0x04	/* h: short */
-#define	SUPPRESS	0x08	/* suppress assignment */
-#define	POINTER		0x10	/* weird %p pointer (`fake hex') */
-#define	NOSKIP		0x20	/* do not skip blanks */
+#define CHAR		0x08	/* hh: 8 bit integer */
+#define	SUPPRESS	0x10	/* suppress assignment */
+#define	POINTER		0x20	/* weird %p pointer (`fake hex') */
+#define	NOSKIP		0x40	/* do not skip blanks */
 
 /*
  * The following are used in numeric conversions only:
@@ -163,14 +164,14 @@ extern _LONG_DOUBLE _strtold _PARAMS((ch
  * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
  */
 
-#define	SIGNOK		0x40	/* +/- is (still) legal */
-#define	NDIGITS		0x80	/* no digits detected */
+#define	SIGNOK		0x80	/* +/- is (still) legal */
+#define	NDIGITS		0x100	/* no digits detected */
 
-#define	DPTOK		0x100	/* (float) decimal point is still legal */
-#define	EXPOK		0x200	/* (float) exponent (e+3, etc) still legal */
+#define	DPTOK		0x200	/* (float) decimal point is still legal */
+#define	EXPOK		0x400	/* (float) exponent (e+3, etc) still legal */
 
-#define	PFXOK		0x100	/* 0x prefix is (still) legal */
-#define	NZDIGITS	0x200	/* no zero digits detected */
+#define	PFXOK		0x200	/* 0x prefix is (still) legal */
+#define	NZDIGITS	0x400	/* no zero digits detected */
 
 /*
  * Conversion types.
@@ -262,6 +263,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
   mbstate_t state;                /* value to keep track of multibyte state */
 #endif
 
+  char *cp;
   short *sp;
   int *ip;
   float *flp;
@@ -335,13 +337,25 @@ __svfscanf_r (rptr, fp, fmt0, ap)
 	  flags |= SUPPRESS;
 	  goto again;
 	case 'l':
-	  flags |= LONG;
+	  if (*fmt == 'l')	/* Check for 'll' = long long (SUSv3) */
+	    {
+	      ++fmt;
+	      flags |= LONGDBL;
+	    }
+	  else
+	    flags |= LONG;
 	  goto again;
 	case 'L':
 	  flags |= LONGDBL;
 	  goto again;
 	case 'h':
-	  flags |= SHORT;
+	  if (*fmt == 'h')	/* Check for 'hh' = char int (SUSv3) */
+	    {
+	      ++fmt;
+	      flags |= CHAR;
+	    }
+	  else
+	    flags |= SHORT;
 	  goto again;
 
 	case '0':
@@ -440,7 +454,12 @@ __svfscanf_r (rptr, fp, fmt0, ap)
 	case 'n':
 	  if (flags & SUPPRESS)	/* ??? */
 	    continue;
-	  if (flags & SHORT)
+	  if (flags & CHAR)
+	    {
+	      cp = va_arg (ap, char *);
+	      *cp = nread;
+	    }
+	  else if (flags & SHORT)
 	    {
 	      sp = va_arg (ap, short *);
 	      *sp = nread;
@@ -808,6 +827,11 @@ __svfscanf_r (rptr, fp, fmt0, ap)
 	      res = (*ccfn) (rptr, buf, (char **) NULL, base);
 	      if (flags & POINTER)
 		*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
+	      else if (flags & CHAR)
+		{
+		  cp = va_arg (ap, char *);
+		  *cp = res;
+		}
 	      else if (flags & SHORT)
 		{
 		  sp = va_arg (ap, short *);


-- 
Corinna Vinschen
Cygwin Developer
Red Hat, Inc.
mailto:vinschen@redhat.com



More information about the Newlib mailing list