[RFA] Add hh and ll modifiers to scanf functions
J. Johnston
jjohnstn@redhat.com
Tue Apr 1 16:01:00 GMT 2003
The patch is fine. If you want to move the internal doc stuff to vfscanf.c, \
that would be fine. Just remember to update stdio.tex and do a make info to
make sure everything still works.
-- Jeff J.
Corinna Vinschen wrote:
> 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 *);
>
>
More information about the Newlib
mailing list