This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Add hh and ll modifiers to scanf functions


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 at vinschen dot 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 at redhat dot com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]